这是关于前缀和算法技巧在二维数组中的应用的一道题。
如何计算给定矩阵中任意区域(即子矩阵)的元素和?当然,每次计算都对二维矩阵进行遍历也是ok的,但是,明显效率比较低。理想做法是维护一个二维数组,记录以矩阵原点为顶点的矩阵的元素和。这样每次计算时可以通过简单的加减法运算得出结果,即用空间换时间。
思路如下:
声明二维数组preSum,preSum[i][j] 表示matrix矩阵中[0, 0, i-1, j-1]所包围的元素之和。
具体代码实现如下:
class NumMatrix {
preSum: number[][]
constructor(matrix: number[][]) {
const m = matrix.length, n = matrix[0].length
this.preSum = new Array(m+1).fill(0).map(() => new Array(n+1).fill(0))
for (let i = 1; i<=m; i++) {
for (let j = 1; j<=n; j++) {
// preSum[i][j] 表示matrix矩阵中[0, 0, i-1, j-1]所包围的元素之和
this.preSum[i][j] = this.preSum[i-1][j] + this.preSum[i][j-1] - this.preSum[i-1][j-1] + matrix[i-1][j-1]
}
}
console.log(this.preSum)
}
sumRegion(row1: number, col1: number, row2: number, col2: number): number {
return this.preSum[row2+1][col2+1] - this.preSum[row2+1][col1] - this.preSum[row1][col2+1] + this.preSum[row1][col1]
}
}
需要注意的是,代码中二维数组preSum,为了边界值更可控,行和列的长度分别为给定矩阵matrix行和列的长度+1。而在计算方法sumRegion中,入参中的row1col1, row2, col2的值,索引都从0起始。因此要特别注意,索引值的对应关系。