304. 二维区域和检索 - 矩阵不可变+308. 二维区域和检索 - 可变

304题目:

给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2)。

 

上图子矩阵左上角 (row1, col1) = (2, 1) ,右下角(row2, col2) = (4, 3),该子矩形内元素的总和为 8。

示例:

给定 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
说明:

你可以假设矩阵不可变。
会多次调用 sumRegion 方法。
你可以假设 row1 ≤ row2 且 col1 ≤ col2。

代码:

每一行保存0~n的前缀和。每次计算矩形的元素和,遍历n行,一共O(n)。

 1 class NumMatrix {
 2 public:
 3     vector<vector<int>> prefix;
 4     NumMatrix(vector<vector<int>>& matrix) {
 5         if(matrix.empty() or matrix[0].empty()){
 6             prefix={{0}};
 7             return;
 8         }
 9         int m=matrix.size(),n=matrix[0].size();
10         prefix.resize(m+1,vector<int>(n+1,0));
11         for(int i=1;i<=m;++i){
12             for(int j=1;j<=n;++j){
13                 prefix[i][j]=prefix[i][j-1]+matrix[i-1][j-1];
14             }
15         }//prefix[i][j]:矩阵第i-1行,0列到j-1列的元素和
16     }
17     int sumRegion(int row1, int col1, int row2, int col2) {
18         int res=0;
19         for(int i=row1+1;i<=row2+1;++i){
20             res+=prefix[i][col2+1]-prefix[i][col1];
21         }
22         return res;
23     }
24 };
25 
26 /**
27  * Your NumMatrix object will be instantiated and called as such:
28  * NumMatrix* obj = new NumMatrix(matrix);
29  * int param_1 = obj->sumRegion(row1,col1,row2,col2);
30  */

308题目:

给你一个 2D 矩阵 matrix,请计算出从左上角 (row1, col1) 到右下角 (row2, col2) 组成的矩形中所有元素的和。

上述粉色矩形框内的,该矩形由左上角 (row1, col1) = (2, 1) 和右下角 (row2, col2) = (4, 3) 确定。其中,所包括的元素总和 sum = 8。

示例:

给定 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
 

注意:

矩阵 matrix 的值只能通过 update 函数来进行修改
你可以默认 update 函数和 sumRegion 函数的调用次数是均匀分布的
你可以默认 row1 ≤ row2,col1 ≤ col2


代码:

原理如下,勉强算作动态规划??(不懂。)

另外304也可以这样做。主要是我不会线段树和树状数组,还好数据量比较小,这个算法也能过。

 1 class NumMatrix {
 2 public:
 3     vector<vector<int>> dp;
 4     NumMatrix(vector<vector<int>>& matrix) {
 5         if(matrix.empty() or matrix[0].empty()){
 6             dp={{0}};
 7             return;
 8         }
 9         int m=matrix.size(),n=matrix[0].size();
10         dp.resize(m+1,vector<int>(n+1,0));
11         //dp[i][j]:matrix以i-1,j-1为右下角的矩形的元素和
12         for(int i=1;i<=n;++i){
13             dp[0][i]=dp[0][i-1]+matrix[0][i-1];
14         }
15         for(int i=1;i<=m;++i){
16             int cur_sum=0;
17             for(int j=1;j<=n;++j){
18                 cur_sum+=matrix[i-1][j-1];
19                 dp[i][j]=dp[i-1][j]+cur_sum;
20             }
21         } 
22     }
23     
24     void update(int row, int col, int val) {
25         int dif=val-(dp[row+1][col+1]-dp[row][col+1]-dp[row+1][col]+dp[row][col]);//差值
26         for(int i=row+1;i<dp.size();++i){
27             for(int j=col+1;j<dp[0].size();++j){
28                 dp[i][j]+=dif;
29             }
30         }
31     }
32     
33     int sumRegion(int row1, int col1, int row2, int col2) {
34         return dp[row2+1][col2+1]-dp[row2+1][col1]-dp[row1][col2+1]+dp[row1][col1];
35     }
36 };
37 
38 /**
39  * Your NumMatrix object will be instantiated and called as such:
40  * NumMatrix* obj = new NumMatrix(matrix);
41  * obj->update(row,col,val);
42  * int param_2 = obj->sumRegion(row1,col1,row2,col2);
43  */

猜你喜欢

转载自www.cnblogs.com/FdWzy/p/12370149.html