从零开始刷力扣(二十七)——304. 二维区域和检索 - 矩阵不可变

分类:前缀和数组

题目描述:

给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2)。

Range Sum Query 2D

上图子矩阵左上角 (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

说明:

  1. 你可以假设矩阵不可变。
  2. 会多次调用 sumRegion 方法
  3. 你可以假设 row1 ≤ row2 且 col1 ≤ col2。

思路:

一开始的思路是暴力破解,即每次sumRegion的时候都双重循环求和;初始化时时间复杂度为O(1),求和时时间复杂度为O((row2-row1)*(clo2-col1))

代码实现:

/**
 * @param {number[][]} matrix
 */
var NumMatrix = function (matrix) {
    this.matrix = matrix;
};

/** 
 * @param {number} row1 
 * @param {number} col1 
 * @param {number} row2 
 * @param {number} col2
 * @return {number}
 */
NumMatrix.prototype.sumRegion = function (row1, col1, row2, col2) {
    let sum = 0;
    for (let i = row1; i <= row2; i++) {
        for (let j = col1; j <= col2; j++) {
            sum += this.matrix[i][j];
        }
    }
    return sum;
};

运行结果:

从零开始刷力扣(二十七)——304. 二维区域和检索 - 矩阵不可变_第1张图片

进阶:

参考了昨天看的一维数组的求和,想到了一个优化的思路
思路:

构造函数初始化时求出(i,j)到(0,0)区域间的和,sumRegion时用大的区域减去不需要计算的区域再加上重合的区域即可;初始化时时间复杂度为O(m*n),sumRegion时时间复杂度为O(1);

代码实现:



/**
 * @param {number[][]} matrix
 */
var NumMatrix = function (matrix) {
    this.accumulateMatrix = [];
    if (matrix.length === 0) return; //确定matrix存在
    var n = matrix.length;
    var m = matrix[0].length;
    for (var i = 0; i <= n; i++) {  //开辟dp空间为 n✖️m的矩阵
        var rows = [];
        for (var j = 0; j <= m; j++) {
            rows[j] = 0;
        }
        this.accumulateMatrix.push(rows);
    }
    for (var i = 1; i <= n; i++) {
        for (var j = 1; j <= m; j++) {
            this.accumulateMatrix[i][j] = matrix[i - 1][j - 1] + this.accumulateMatrix[i - 1][j]
                + this.accumulateMatrix[i][j - 1] - this.accumulateMatrix[i - 1][j - 1];
        }
    }
};

/** 
 * @param {number} row1 
 * @param {number} col1 
 * @param {number} row2 
 * @param {number} col2
 * @return {number}
 */
NumMatrix.prototype.sumRegion = function (row1, col1, row2, col2) {
    return this.accumulateMatrix[row2 + 1][col2 + 1] - this.accumulateMatrix[row1][col2 + 1]
        - this.accumulateMatrix[row2 + 1][col1] + this.accumulateMatrix[row1][col1];

};

运行结果:

从零开始刷力扣(二十七)——304. 二维区域和检索 - 矩阵不可变_第2张图片

你可能感兴趣的:(LeetCode,leetcode,算法)