Question:
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).
The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.
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 sumRegion(1, 1, 2, 2) -> 11 sumRegion(1, 2, 2, 4) -> 12
Note:
- You may assume that the matrix does not change.
- There are many calls to sumRegion function.
- You may assume that row1 ≤ row2 and col1 ≤ col2.
Analysis:
这是前面做的一个题目的升级版本,由原来的一维计算变为二维。http://www.cnblogs.com/little-YTMM/p/5188699.html 由于题目要求是一致的,因此思路也是一样的:在构造函数中存储中间和,然后在求和函数中利用中间和进行简单的计算,节省计算时间。
在构造函数中计算中间和时,我们使每个元素存储从0至所有小于等于该行该列的数的和。(之前思路是,按行存储所有前面元素的和,这样到后面求和函数时要考虑N多种情况,特别复杂,于是放弃了。)
Answer:
public class NumMatrix { int[][] num; public NumMatrix(int[][] matrix) { num = null; if(matrix.length >0 && matrix[0].length > 0) { num = new int[matrix.length][matrix[0].length]; for(int i=0; i<matrix.length; i++) { for(int j=0; j<matrix[0].length; j++) { if(i == 0) { if(j == 0) num[i][j] = matrix[i][j]; else num[i][j] = matrix[i][j] + num[i][j-1]; } else { //i != 0 if(j == 0) num[i][j] = matrix[i][j] + num[i-1][j]; else num[i][j] = num[i][j-1] + num[i-1][j] - num[i-1][j-1] + matrix[i][j]; } } } } } public int sumRegion(int row1, int col1, int row2, int col2) { if(row1 == 0 && col1 == 0) return num[row2][col2]; else if(row1 == 0) return num[row2][col2] - num[row2][col1-1]; else if(col1 == 0) return num[row2][col2] - num[row1-1][col2]; else return num[row2][col2] - num[row2][col1-1] - num[row1-1][col2] + num[row1-1][col1-1]; } } // Your NumMatrix object will be instantiated and called as such: // NumMatrix numMatrix = new NumMatrix(matrix); // numMatrix.sumRegion(0, 1, 2, 3); // numMatrix.sumRegion(1, 2, 3, 4);