力扣刷题笔记--304 二维区域和检索 - 矩阵不可变 前缀和
Posted HardyDragon_CC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣刷题笔记--304 二维区域和检索 - 矩阵不可变 前缀和相关的知识,希望对你有一定的参考价值。
304 二维区域和检索 - 矩阵不可变
作者:AC_OIer
链接:https://leetcode-cn.com/problems/range-sum-query-2d-immutable/solution/xia-ci-ru-he-zai-30-miao-nei-zuo-chu-lai-ptlo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
思路:
二维前缀和解决的是二维矩阵中的矩形区域求和问题。
二维前缀和数组中的每一个格子记录的是「以当前位置为区域的右下角(区域左上角恒定为原数组的左上角)的区域和」
即 sum 的每个元素表示其区域和。
假设 i 和 j 为固定值 3 来理解。
如何初始化sum中的元素 , (sum 的每个元素表示其区域和);
根据上图可知,就是求 f[i][j] ;
因此当我们要求 (x1, y1) 作为左上角,(x2, y2) 作为右下角 的区域和的时候,可以直接利用前缀和数组快速求解:
至于求子矩阵元素和就是求 matrix[i][j];
class NumMatrix {
int[][] sum;
public NumMatrix(int[][] matrix) {
int n = matrix.length, m = n == 0 ? 0 : matrix[0].length;
// 与「一维前缀和」一样,前缀和数组下标从 1 开始,因此设定矩阵形状为 [n + 1][m + 1](模板部分)
sum = new int[n + 1][m + 1];
// 预处理除前缀和数组(模板部分)
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + matrix[i - 1][j - 1];
}
}
}
public int sumRegion(int x1, int y1, int x2, int y2) {
// 求某一段区域和 [i, j] 的模板是 sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];(模板部分)
// 但由于我们源数组下标从 0 开始,因此要在模板的基础上进行 + 1
x1++; y1++; x2++; y2++;
return sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
}
}
以上是关于力扣刷题笔记--304 二维区域和检索 - 矩阵不可变 前缀和的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 0304. 二维区域和检索 - 矩阵不可变