题目
Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (_row_1, _col_1) and lower right corner (_row_2, _col_2).
The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.
Example:
Given 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) -> 8sumRegion(1, 1, 2, 2) -> 11sumRegion(1, 2, 2, 4) -> 12
Note:
- You may assume that the matrix does not change.
- There are many calls to sumRegion function.
- You may assume that _row_1 ≤ _row_2 and _col_1 ≤ _col_2.
题意
给定一个整数矩阵,求其中一个子矩阵的数字之和。
思路
一种方法是在0303. Range Sum Query - Immutable (E)的基础上,将矩阵中每一行的sum情况缓存,求指定矩阵和时,只要累加该矩阵每一行对应的sum值即可。
更好的策略是将一维缓存的方法进行推广,进行二维缓存:
代码实现
Java
一维缓存
class NumMatrix {private int[][] sum;public NumMatrix(int[][] matrix) {if (matrix.length != 0) {sum = new int[matrix.length][matrix[0].length + 1];for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {sum[i][j + 1] += sum[i][j] + matrix[i][j];}}}}public int sumRegion(int row1, int col1, int row2, int col2) {int total = 0;for (int i = row1; i <= row2; i++) {total += sum[i][col2 + 1] - sum[i][col1];}return total;}}
二维缓存
class NumMatrix {private int[][] sum;public NumMatrix(int[][] matrix) {if (matrix.length > 0) {int m = matrix.length, n = matrix[0].length;sum = new int[m + 1][n + 1];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] + matrix[i][j] - sum[i][j];}}}}public int sumRegion(int row1, int col1, int row2, int col2) {return sum[row2 + 1][col2 + 1] - sum[row2 + 1][col1] - sum[row1][col2 + 1] + sum[row1][col1];}}
JavaScript
/*** @param {number[][]} matrix*/var NumMatrix = function (matrix) {const m = matrix.lengthconst n = matrix[0].lengththis.sumMatrix = new Array(m + 1).fill(0).map(item => [])for (let i = 0; i < m; i++) {let rowSum = 0;for (let j = 0; j < n; j++) {rowSum += matrix[i][j]this.sumMatrix[i][j] = i === 0 ? rowSum : rowSum + this.sumMatrix[i - 1][j]}}}/*** @param {number} row1* @param {number} col1* @param {number} row2* @param {number} col2* @return {number}*/NumMatrix.prototype.sumRegion = function (row1, col1, row2, col2) {const a = this.sumMatrix[row2][col2]const b = col1 > 0 ? this.sumMatrix[row2][col1 - 1] : 0const c = row1 > 0 ? this.sumMatrix[row1 - 1][col2] : 0const d = row1 > 0 && col1 > 0 ? this.sumMatrix[row1 - 1][col1 - 1] : 0return a - b - c + d}
