304. 二维区域和检索 - 矩阵不可变(JavaScript)
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (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。
思路:
这是系列题,第一题请看区域和检索-数组不可变。
思路是一样的,同样,在NumMatrix中,新建一个矩阵,他的每个元素是原matrix最左上角与该元素组成的小矩阵的总和。
第二步,要求矩阵的和,直接使用四个元素的加法减法即可。
/**
* @param {number[][]} matrix
*/
var NumMatrix = function(matrix) {
if (matrix.length === 0) this.mat = [[]];
else {
let mat = [[matrix[0][0]]], // 此矩阵的每个元素为从最左上角到该元素组成的小矩阵的和
row = matrix.length,
col = matrix[0].length;
for (let i = 1; i < row; ++i) {
mat.push([matrix[i][0] + mat[i-1][0]]); // 第一列
}
for (let j = 1; j < col; ++j) {
mat[0].push(matrix[0][j] + mat[0][j-1]); // 第一行
}
for (let i = 1; i < row; ++i) {
for (let j = 1; j < col; ++j) {
mat[i][j] = matrix[i][j] + mat[i-1][j] + mat[i][j-1] - mat[i-1][j-1]; // 矩阵其余元素
}
}
this.mat = mat;
}
};
/**
* @param {number} row1
* @param {number} col1
* @param {number} row2
* @param {number} col2
* @return {number}
*/
NumMatrix.prototype.sumRegion = function(row1, col1, row2, col2) {
if (row1 === 0) {
if (col1 === 0) { return this.mat[row2][col2]; }
else { return this.mat[row2][col2] - this.mat[row2][col1-1]; }
} else {
if (col1 === 0) { return this.mat[row2][col2] - this.mat[row1-1][col2]; }
else { return this.mat[row2][col2] - this.mat[row1-1][col2] - this.mat[row2][col1-1] + this.mat[row1-1][col1-1]; }
}
};
/**
* Your NumMatrix object will be instantiated and called as such:
* var obj = Object.create(NumMatrix).createNew(matrix)
* var param_1 = obj.sumRegion(row1,col1,row2,col2)
*/