二维区域和检索

74 阅读1分钟

304. 二维区域和检索 - 矩阵不可变

这是关于前缀和算法技巧在二维数组中的应用的一道题。

截屏2023-07-17 20.35.16.png


如何计算给定矩阵中任意区域(即子矩阵)的元素和?当然,每次计算都对二维矩阵进行遍历也是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起始。因此要特别注意,索引值的对应关系。