Range Sum Query 2D - Mutable

Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2).

Range Sum Query 2D - Mutable - 图1

The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.

Example:

  1. Given matrix = [
  2. [3, 0, 1, 4, 2],
  3. [5, 6, 3, 2, 1],
  4. [1, 2, 0, 1, 5],
  5. [4, 1, 0, 1, 7],
  6. [1, 0, 3, 0, 5]
  7. ]
  8. sumRegion(2, 1, 4, 3) -> 8
  9. update(3, 2, 2)
  10. sumRegion(2, 1, 4, 3) -> 10

Solution:

  1. public class NumMatrix {
  2. int m, n;
  3. int[][] arr; // stores matrix[][]
  4. int[][] BITree; // 2-D binary indexed tree
  5. public NumMatrix(int[][] matrix) {
  6. if (matrix.length == 0 || matrix[0].length == 0) {
  7. return;
  8. }
  9. m = matrix.length;
  10. n = matrix[0].length;
  11. arr = new int[m][n];
  12. BITree = new int[m + 1][n + 1];
  13. for (int i = 0; i < m; i++) {
  14. for (int j = 0; j < n; j++) {
  15. update(i, j, matrix[i][j]); // init BITree[][]
  16. arr[i][j] = matrix[i][j]; // init arr[][]
  17. }
  18. }
  19. }
  20. public void update(int i, int j, int val) {
  21. int diff = val - arr[i][j];
  22. arr[i][j] = val;
  23. i++; j++;
  24. while (i <= m) {
  25. int k = j;
  26. while (k <= n) {
  27. BITree[i][k] += diff;
  28. k += k & (-k);
  29. }
  30. i += i & (-i);
  31. }
  32. }
  33. int getSum(int i, int j) {
  34. int sum = 0;
  35. i++; j++;
  36. while (i > 0) {
  37. int k = j;
  38. while (k > 0) {
  39. sum += BITree[i][k];
  40. k -= k & (-k);
  41. }
  42. i -= i & (-i);
  43. }
  44. return sum;
  45. }
  46. public int sumRegion(int i1, int j1, int i2, int j2) {
  47. return getSum(i2, j2) - getSum(i1-1, j2) - getSum(i2, j1-1) + getSum(i1-1, j1-1);
  48. }
  49. }
  50. // Your NumMatrix object will be instantiated and called as such:
  51. // NumMatrix numMatrix = new NumMatrix(matrix);
  52. // numMatrix.sumRegion(0, 1, 2, 3);
  53. // numMatrix.update(1, 1, 10);
  54. // numMatrix.sumRegion(1, 2, 3, 4);