力扣_304_矩阵不可变(中等)

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

3 0 1 4 2
5 6 3 2 1
1 2 0 1 5
1 0 3 0 5

上图子矩阵左上角 (row1, col1) = (2, 1) ,右下角(row2, col2) = (4, 3),该子矩形内元素的总和为 8。

 

 

这个题就是上一题的进化版...

根据上一题从答案提取的精华,有两种解决方法:

①、1.计算每一行的前缀和

  2.计算每一列的前缀和(貌似跟第一个差不太多)

②、计算二位数组总的前缀和

一、计算每一行的前缀和

class NumMatrix {
    public int[][] sums;

    public NumMatrix(int[][] matrix) {
        int n = matrix.length;
        sums = new int[n][];

        for (int i = 0; i < n; i++) {
            sums[i] = new int[matrix[i].length+1];
            for (int j = 1; j < sums[i].length; j++) {
                if(j == 1){
                    sums[i][j] = matrix[i][j-1];
                }else{
                    sums[i][j] = sums[i][j-1] + matrix[i][j-1];
                }
            }
        }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
        int sum1 = 0;
        int sum2 = 0;

        for (int i = row1; i <= row2; i++) {
            sum1 += sums[i][col2+1];
            sum2 += sums[i][col1];
        }

        return sum1 - sum2;
    }
}

注:第一列仍然是为了预防sumRegin(0,0,row2,col2)这种情况

二、计算二位数组总的前缀和

class NumMatrix {
    public int[][] sums;

    public NumMatrix(int[][] matrix) {
        int n = matrix.length;

        if(n > 0) {
            int m = matrix[0].length;
            sums = new int[n + 1][m + 1];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (i == 0) {
                        sums[i + 1][j + 1] = sums[i + 1][j] + matrix[i][j];
                    } else if (j == 0) {
                        sums[i + 1][j + 1] = sums[i][j + 1] + matrix[i][j];
                    } else {
                        sums[i + 1][j + 1] = sums[i + 1][j] + sums[i][j + 1] - sums[i][j] + matrix[i][j];
                    }
                }
            }
        }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
        return sums[row2+1][col2+1] - sums[row2+1][col1] - sums[row1][col2+1] + sums[row1][col1];
    }
}

注:第一列、第一行仍然是为了预防sumRegin(0,0,row2,col2)这种情况

posted @ 2021-03-03 10:38  '--'  阅读(63)  评论(0)    收藏  举报