题目大意:
二维区域和检索 – 可变
给你一个 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
提示:
- 矩阵的值仅可以被update函数更新
- 您可以假设对update的调用次数和sumRegion函数的调用次数是均匀分布的。
- 您可以假设 row1 ≤ row2 并且 col1 ≤ col2.
如果想查看本题目是哪家公司的面试题,请参考以下免费链接: https://leetcode.jp/problemdetail.php?id=308
解题思路分析:
本题可以采用前缀和来解题,我们之前做过很多一维数组前缀和的问题,本题则是二维数组版本,二维数组前缀和presum[][],求的是任意一点与[0, 0]点围成的区间内所有数字和。求出前缀和数组之后,对于任意区间内[x1, y1], [x2, y2]的数值和应该等于:
sum([x1,y1],[x2,y2]) = presum[x2][y2]
- presum[x1-1][y2]
- presum[x2][y1-1]
+ presum[x1-1][y1-1]; 如果感觉公式过于抽象,我们可以参考下图:
上图最左侧红色区域是我们想求和的区域,它的和应该等于蓝色区域减去2个黄色区域的值,而被减去的2个黄色区域存在一个橘红色重复区域(参照上图最右侧),因此还要再加上这个橘色区域即是我们想求的红色区域和。对于蓝色,黄色以及橘色区域都是前缀和数组中存在的值。
解题时,我们需要在构造函数中构建出前缀和数组,sumRegion方法中按照上面的公式求和。update方法中,我们不仅需要更改原矩阵中相对应的数值,另外我们还需要更改前缀和数组中相对应的所有值。即大于等于更新点横坐标并且大于等于更新点纵坐标范围的所有值。
实现代码:
int[][] presum; // 前缀和数组
int[][] m; // 原数组
public NumMatrix(int[][] matrix) {
m=matrix;
if(m.length==0) return;
// 初始化前缀和数组
presum=new int[matrix.length][matrix[0].length];
// 计算所有前缀和
for(int r=0;r<matrix.length;r++){
int sum=0;
for(int c=0;c<matrix[0].length;c++){
sum+=matrix[r][c];
presum[r][c]=sum+(r>0?presum[r-1][c]:0);
}
}
}
public void update(int row, int col, int val) {
// 查看更新后值的变化
int diff=val-m[row][col];
// 更新元素组中对应的数值
m[row][col]=val;
// 更新前缀和数组中的值
for(int r=row;r<m.length;r++){
for(int c=col;c<m[0].length;c++){
presum[r][c]+=diff;
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
// 利用前缀和计算当前区域和
return presum[row2][col2]
- (row1>0?presum[row1-1][col2]:0)
- (col1>0?presum[row2][col1-1]:0)
+ (row1>0&&col1>0?presum[row1-1][col1-1]:0);
} 本题解法执行时间为41ms。
Runtime: 41 ms, faster than 20.71% of Java online submissions for Range Sum Query 2D – Mutable.
Memory Usage: 44.6 MB, less than 21.43% of Java online submissions for Range Sum Query 2D – Mutable.
本网站文章均为原创内容,并可随意转载,但请标明本文链接如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/leetcode-308-range-sum-query-2d-mutable-解题思路分析/
View Comments (0)