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 */