标签:
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).
Example:
Given matrix = [
[3, 0, 1, 4, 2],
[5, 6, 3, 2, 1],
[1, 2, 0, 1, 5],
[4, 1, 0, 1, 7],
[1, 0, 3, 0, 5]
]
sumRegion(2, 1, 4, 3) -> 8
update(3, 2, 2)
sumRegion(2, 1, 4, 3) -> 10
Note:
The matrix is only modifiable by the update function.
You may assume the number of calls to update and sumRegion function is distributed evenly.
You may assume that row1 ≤ row2 and col1 ≤ col2.
分析:https://segmentfault.com/a/1190000004238792
注意这道题说明了"calls to update and sumRegion function is distributed evenly"
。我们可以先不考虑这道题的限制,根据这个两个方法使用次数分情况讨论:
update多,sumRegion少
这种情况比较简单,我们可以直接复制矩阵,update的时候直接update对应点的值即可,sumRegion直接遍历指定范围内的值就可以了。
update: O(1), sumRegion: O(mn)
update少,sumRegion多。
我们可以不复制整个矩阵,而是在每个点处存(0, 0)到该的长方形内所有元素的和,这样的话,sumRegion的复杂度会很低,update的时候我们需要update所有受影响的sum。
update: O(mn), sumRegion: O(1)
update多,sumRegion多(本题情况)
我们可以每个点存对于该行,起始点到该点为止的sum。这样话,update的话,我们只需要update该行受影响的sum即可。sumRegion的话,我们只需要遍历相应行,加上不同行的对应sum即可。
update: O(n), sumRegion: O(m)
当然,对于这种类型的题目,使用一些高级数据结构会更时间复杂度会更低,能达到logn,如二维线段树。这里只涉及基本的数据结构,尽量不搞复杂。
注:m指行数,n指列数,这里global的矩阵不算各个方法的extra space。
time: O(n), space: O(1)
time: O(m), space: O(1)
1 public class NumMatrix { 2 int[][] rowSums; 3 4 public NumMatrix(int[][] matrix) { 5 if (matrix.length == 0) 6 return; 7 rowSums = new int[matrix.length][matrix[0].length]; 8 9 // 建rowSums矩阵 10 for (int i = 0; i < matrix.length; i++) { 11 for (int j = 0; j < matrix[0].length; j++) { 12 rowSums[i][j] = matrix[i][j] + (j == 0 ? 0 : rowSums[i][j - 1]); 13 } 14 } 15 } 16 17 public void update(int row, int col, int val) { 18 // 求出新值与旧值的差 19 int diff = val - (rowSums[row][col] - (col == 0 ? 0 : rowSums[row][col - 1])); 20 21 // 更新该行受影响的sum 22 for (int j = col; j < rowSums[0].length; j++) { 23 rowSums[row][j] += diff; 24 } 25 } 26 27 public int sumRegion(int row1, int col1, int row2, int col2) { 28 int res = 0; 29 30 // 逐行求和,每行的相应和为两sum相减 31 for (int i = row1; i <= row2; i++) { 32 res += rowSums[i][col2] - (col1 == 0 ? 0 :rowSums[i][col1 - 1]); 33 } 34 return res; 35 } 36 } 37 38 39 // Your NumMatrix object will be instantiated and called as such: 40 // NumMatrix numMatrix = new NumMatrix(matrix); 41 // numMatrix.sumRegion(0, 1, 2, 3); 42 // numMatrix.update(1, 1, 10); 43 // numMatrix.sumRegion(1, 2, 3, 4);
Range Sum Query 2D - Mutable & Immutable
就是没有update操作,这样的话,我们直接找出0,0 到每个点的和即可。
1 public class NumMatrix { 2 int[][] matrix; 3 4 public NumMatrix(int[][] m) { 5 matrix = m; 6 if (m == null || m.length == 0 || m[0].length == 0) return; 7 for (int i = 1; i < matrix[0].length; i++) { 8 matrix[0][i] += matrix[0][i - 1]; 9 } 10 11 for (int i = 1; i < matrix.length; i++) { 12 matrix[i][0] += matrix[i - 1][0]; 13 } 14 15 for (int i = 1; i < matrix.length; i++) { 16 for (int j = 1; j < matrix[0].length; j++) { 17 matrix[i][j] += matrix[i - 1][j] + matrix[i][j - 1] - matrix[i - 1][j - 1]; 18 } 19 } 20 } 21 22 public int sumRegion(int row1, int col1, int row2, int col2) { 23 if (matrix == null) return 0; 24 25 if (row1 == 0 && col1 == 0) return matrix[row2][col2]; 26 if (row1 == 0) return matrix[row2][col2] - matrix[row2][col1 - 1]; 27 if (col1 == 0) return matrix[row2][col2] - matrix[row1 - 1][col2]; 28 29 return matrix[row2][col2] - matrix[row1 - 1][col2] - matrix[row2][col1 - 1] + matrix[row1 - 1][col1 - 1]; 30 } 31 } 32 33 34 // Your NumMatrix object will be instantiated and called as such: 35 // NumMatrix numMatrix = new NumMatrix(matrix); 36 // numMatrix.sumRegion(0, 1, 2, 3); 37 // numMatrix.sumRegion(1, 2, 3, 4);
Range Sum Query 2D - Mutable & Immutable
标签:
原文地址:http://www.cnblogs.com/beiyeqingteng/p/5745122.html