题目
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2) 。
上图子矩阵左上角 (row1, col1) = (2, 1) ,右下角(row2, col2) = (4, 3),该子矩形内元素的总和为 8。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-query-2d-immutable
解法:
利用前缀和
前缀和: 前缀和是一个数组的某项下标之前(包括此项元素)的所有数组元素的和
定义式 | 递推式 | |
一维前缀和 | ||
二维前缀和 |
1. 一维前缀和
preSum[i][j] 表示 矩阵第i+1行 上matrix[i][0]到matrix[i][j]的和
class NumMatrix
private int[][] preSum;
private int[][] matrix;
public NumMatrix(int[][] matrix) {
this.matrix = matrix;
int n = matrix.length;
if(n>0){
int m = matrix[0].length;
preSum = new int[n][m];
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < m; ++j)
{
preSum[i][j] = matrix[i][j];
if(j-1>=0) preSum[i][j] += preSum[i][j-1];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
//溢出判断
int n = matrix.length, m = matrix[0].length; if(row1<0||row2<0||row1>=n||row2>=n||col1<0||col2<0||col1>=m||col2>=m)
return 0;
int i = row1,sum = 0;
while(i<=row2 )
{
sum += preSum[i][col2] - preSum[i][col1] + matrix[i][col1];
// System.out.println(preSum[i][col1]+" "+preSum[i][col2] +" "+matrix[i][col1]+" :"+sum);
i++;
}
return sum;
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/
2. 二维前缀和
dp[i][j] 就是指dp[0][0]到dp[i][j]围成的矩形部分的和;
图片作者:zui-weng-jiu-xian
链接:https://leetcode-cn.com/problems/range-sum-query-2d-immutable/solution/er-wei-qu-yu-he-jian-suo-bu-bu-shen-ru-c-t2g7/
class NumMatrix {
public int[][] dp;
public NumMatrix(int[][] matrix) {
dp = matrix;
int n = matrix.length ;
if(n>0)
{
int m = matrix[0].length;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; ++j)
{
if(i-1>=0)
dp[i][j]+=dp[i-1][j];
if(j-1>=0)
dp[i][j]+=dp[i][j-1];
if(j-1>=0&&i-1>=0)
dp[i][j]-=dp[i-1][j-1];
}
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
//溢出判断
int n = dp.length;
if(n>0)
{
int m = dp[0].length; if(row1<0||row2<0||row1>=n||row2>=n||col1<0||col2<0||col1>=m||col2>=m)
return 0;
int sum = dp[row2][col2];
if(row1-1>=0) sum-=dp[row1-1][col2];
if(col1-1>=0) sum-=dp[row2][col1-1];
if(row1-1>=0 && col1-1>=0) sum+=dp[row1-1][col1-1];
return sum;
}
return 0;
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/