题目链接
剑指 Offer II 013. 二维子矩阵的和 mid
题目描述
给定一个二维矩阵 matrix
,以下类型的多个请求:
- 计算其子矩形范围内元素的总和,该子矩阵的左上角为
(row1, col1)
,右下角为(row2, col2)
。
实现 NumMatrix
类:
NumMatrix(int[][] matrix)
给定整数矩阵matrix
进行初始化int sumRegion(int row1, int col1, int row2, int col2)
返回左上角(row1, col1)
、右下角(row2, col2)
的子矩阵的元素总和。
示例 1:
输入:
[“NumMatrix”,“sumRegion”,“sumRegion”,“sumRegion”]
[[[[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]]],[2,1,4,3],[1,1,2,2],[1,2,2,4]]
输出:
[null, 8, 11, 12]解释: NumMatrix numMatrix = new
NumMatrix([[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]]]);
numMatrix.sumRegion(2, 1, 4, 3); // return 8 (红色矩形框的元素总和)
numMatrix.sumRegion(1, 1, 2, 2); // return 11 (绿色矩形框的元素总和)
numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)
提示:
- m = = m a t r i x . l e n g t h m == matrix.length m==matrix.length
- n = = m a t r i x [ i ] . l e n g t h n == matrix[i].length n==matrix[i].length
- 1 < = m , n < = 200 1 <= m, n <= 200 1<=m,n<=200
- − 1 0 5 < = m a t r i x [ i ] [ j ] < = 1 0 5 -10^5 <= matrix[i][j] <= 10^5 −105<=matrix[i][j]<=105
- 0 < = r o w 1 < = r o w 2 < m 0 <= row1 <= row2 < m 0<=row1<=row2<m
- 0 < = c o l 1 < = c o l 2 < n 0 <= col1 <= col2 < n 0<=col1<=col2<n
- 最多调用
1
0
4
10^4
104 次
sumRegion
方法
分析:
我们定义
s
(
i
,
j
)
s(i,j)
s(i,j) 为从 (0,0)
到 (i,j)
的二为前缀和(红色的部分)。
由图可知,
s
(
i
,
j
)
s(i,j)
s(i,j) 由四部分组成,即
s
(
i
,
j
)
=
s
(
i
−
1
,
j
)
+
s
(
i
,
j
−
1
)
−
s
(
i
−
1
,
j
−
1
)
+
m
a
t
r
i
x
(
i
,
j
)
s(i,j) = s(i-1,j) + s(i,j-1) - s(i-1,j-1) + matrix(i,j)
s(i,j)=s(i−1,j)+s(i,j−1)−s(i−1,j−1)+matrix(i,j)。
同理,两个点包围的区间和也由 四部分组成 如下所示:
所以区间 [r1,c1]
到[r2,c2]
的区间和为 :
s
(
r
2
,
c
2
)
−
s
(
r
1
−
1
,
c
2
)
−
s
(
r
2
,
c
1
−
1
)
+
s
(
r
1
−
1
,
c
1
−
1
)
s(r2,c2) - s(r1-1,c2) - s(r2,c1 - 1) + s(r1-1,c1-1)
s(r2,c2)−s(r1−1,c2)−s(r2,c1−1)+s(r1−1,c1−1)。
时间复杂度: O ( m n ) O(mn) O(mn)
C++代码:
class NumMatrix {
public:
vector<vector<int>> s;
NumMatrix(vector<vector<int>>& matrix) {
int m = matrix.size() , n = matrix[0].size();
s.resize(m + 1,vector<int>(n + 1,0));
for(int i = 1;i <= m;i++){
for(int j = 1;j <= n;j++){
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + matrix[i-1][j-1];
}
}
}
int sumRegion(int r1, int c1, int r2, int c2) {
r1++,c1++;
r2++,c2++;
return s[r2][c2] - s[r2][c1-1] - s[r1-1][c2] + s[r1-1][c1-1];
}
};
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix* obj = new NumMatrix(matrix);
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
*/
Java代码:
class NumMatrix {
int[][] s;
public NumMatrix(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
s = new int[m+1][n+1];
for(int i = 1;i <= m;i++){
for(int j = 1;j <= n;j++){
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + matrix[i-1][j-1];
}
}
}
public int sumRegion(int r1, int c1, int r2, int c2) {
r1++;
c1++;
r2++;
c2++;
return s[r2][c2] - s[r1-1][c2] - s[r2][c1-1] + s[r1-1][c1-1];
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/