题目描述:
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.Note:
1. You may assume that the matrix does not change.
2. There are many calls to sumRegion function.
3. You may assume that row1 ≤ row2 and col1 ≤ col2.
题目分析:
题目和前面#303题相同,只不过将一维数组换成了二维矩阵。用与前一题类似的方法,我们用mymatrix[i][j]
表示矩阵中(i+1,j+1)
到(0,0)
元素中所有元素的和,如图所示:
蓝色的点为matrix[i][j]
元素,两个橘色的点为matrix[i - 1][j]
和matrix[i][j - 1]
元素,绿点为matrix[i - 1][j - 1]
元素,由图可见,如果我们计算matrix[i][j] + mymatrix[i][j + 1] + mymatrix[i + 1][j]
,阴影部分会被叠加两次,应减掉,因此我们计算mymatrix
为
mymatrix[i + 1][j + 1] = matrix[i][j] + mymatrix[i][j + 1] + mymatrix[i + 1][j] - mymatrix[i][j]
。
下面就使用mymatrix
数组去计算要求的sumRegion
了。继续看图:
蓝色的点为(row2, col2)
元素,绿色的点为(row1, col1)
元素。我们要求的sumRegion
就是图中黄色阴影部分。如果我们计算mymatrix[row2 + 1][col2 + 1] - mymatrix[row2 + 1][col1] - mymatrix[row1][col2 + 1]
,即图中绿色矩形减去两个红色矩形,那么蓝色阴影部分被减了两次,应加回。因此我们计算最后的sumRegion
为:
mymatrix[row2 + 1][col2 + 1] - mymatrix[row2 + 1][col1] - mymatrix[row1][col2 + 1] + mymatrix[row1][col1];
具体实现代码如下所示。代码的空间复杂度为
O(n2)
,创建NumMatrix
的时间复杂度为
O(n2)
,计算sumRegion
的时间复杂度为
O(1)
。
class NumMatrix {
public:
NumMatrix(vector<vector<int>> matrix){
int rows = matrix.size();
int cols = rows == 0 ? 0 : matrix[0].size();
mymatrix = vector<vector<int>>(rows+1, vector<int>(cols+1, 0));
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
mymatrix[i + 1][j + 1] = matrix[i][j] + mymatrix[i][j + 1]
+ mymatrix[i + 1][j] - mymatrix[i][j];
}
}
}
int sumRegion(int row1, int col1, int row2, int col2) {
return mymatrix[row2 + 1][col2 + 1] - mymatrix[row2 + 1][col1]
- mymatrix[row1][col2 + 1] + mymatrix[row1][col1];
}
private:
vector<vector<int>> mymatrix;
};
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/