Leetcode 304. 二维区域和检索 - 矩阵不可变,难度:Medium。
原题请戳这里。
题目描述
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2) 。
上图子矩阵左上角 (row1, col1) = (2, 1) ,右下角(row2, col2) = (4, 3),该子矩形内元素的总和为 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
sumRegion(1, 1, 2, 2) -> 11
sumRegion(1, 2, 2, 4) -> 12
提示:
- 你可以假设矩阵不可变。
- 会多次调用
sumRegion方法。 - 你可以假设
row1 ≤ row2且col1 ≤ col2。
思路分析
由昨天的经验在前,今天的打卡题很明确就想到了前缀和。与昨天的数组不同,本题是一个矩阵,2维数组,所以我们这次需要进行2维前缀和的求解。
话不多说,直接动手:
- 需要开辟一个2维前缀和矩阵
preMatrix[m+1][n+1],用于存储前缀和 - 给所有位填上
0进行初始化 - 遍历原矩阵
matrix[][],preMatrix[i + 1][j + 1] = preSum[i][j - 1] + preSum[i - 1][j] - preSum[i - 1][j - 1] + matrix[i][j](需要画个图看下) - 生成前缀和矩阵
preMatrix[]后,需要求原数组中(row1, col1)到(row2, col2)子矩阵内元素的总和,即是求preMatrix[row2][col2] - preMatrix[row2][col1 - 1] - preMatrix[row1 - 1][col2] + preMatrix[row1 - 1][col1 - 1] - 注意,由于前缀和矩阵开的比原矩阵多一行、多一列,所以最后求和时所有下标需要 +1
AC代码
/**
* @param {number[][]} matrix
*/
var NumMatrix = function(matrix) {
const rowLen = matrix.length;
if (rowLen > 0) {
const colLen = matrix[0].length;
this.preMatrix = new Array(rowLen + 1).fill(0).map(() => new Array(colLen + 1).fill(0));
for (let i = 0; i < rowLen; i++) {
for (let j = 0; j < colLen; j++) {
this.preMatrix[i + 1][j + 1] = this.preMatrix[i][j + 1] + this.preMatrix[i + 1][j] - this.preMatrix[i][j] + matrix[i][j];
}
}
}
};
/**
* @param {number} row1
* @param {number} col1
* @param {number} row2
* @param {number} col2
* @return {number}
*/
NumMatrix.prototype.sumRegion = function(row1, col1, row2, col2) {
return this.preMatrix[row2 + 1][col2 + 1] - this.preMatrix[row2 + 1][col1] - this.preMatrix[row1][col2 + 1] + this.preMatrix[row1][col1];
};
/**
* Your NumMatrix object will be instantiated and called as such:
* var obj = new NumMatrix(matrix)
* var param_1 = obj.sumRegion(row1,col1,row2,col2)
*/
总结
本题相似题目:
用到的js语言技巧
this.preMatrix = new Array(rowLen + 1).fill(0).map(() => new Array(colLen + 1).fill(0));,初始化矩阵
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情