题目
类型:前缀和
解题思路
这题的思路和 303. 区域和检索 - 数组不可变 中一维数组中的前缀和问题是非常类似的,如下图:
如果我想计算红色的这个子矩阵的元素之和,可以用绿色矩阵减去蓝色矩阵减去橙色矩阵最后加上粉色矩阵,而绿蓝橙粉这四个矩阵有一个共同的特点,就是左上角就是 (0, 0) 原点。
那么我们可以维护一个二维 preSum 数组,专门记录以原点为顶点的矩阵的元素之和,就可以用几次加减运算算出任何一个子矩阵的元素和。
代码
class NumMatrix {// preSum[i][j] 记录矩阵 [0, 0, i, j] 的元素和private int[][] preSum;public NumMatrix(int[][] matrix) {int m = matrix.length, n = matrix[0].length;if (m == 0 || n == 0) return;// 构造前缀和矩阵preSum = new int[m + 1][n + 1];for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {// 计算每个矩阵 [0, 0, i, j] 的元素和preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i - 1][j - 1] - preSum[i-1][j-1];}}}// 计算子矩阵 [x1, y1, x2, y2] 的元素和public int sumRegion(int x1, int y1, int x2, int y2) {// 目标矩阵之和由四个相邻矩阵运算获得return preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];}}
