308. Range Sum Query 2D

最后更新

二刷。
10-Jan-2017

树状数组的话(FenWickTree)从一维延展到二维,并没有影响使用。

直接秒掉好吧。。太爽了。

Time:

init: (MNlgMN)
query/update : lgMN

public class NumMatrix {
    int[][] matrix;
    int[][] fenWickTree;

    public NumMatrix(int[][] matrix) {
        
        if (matrix.length == 0) return;
        
        this.matrix = new int[matrix.length][matrix[0].length];
        this.fenWickTree = new int[matrix.length + 1][matrix[0].length + 1];
        
        // Tinker: Initialization in 3..2..1..
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                update(i, j, matrix[i][j]);
            }
        }
    }

    public void update(int row, int col, int val) {
        int diff = val - matrix[row][col];
        matrix[row][col] = val;
        
        // Huskar: Thx..for another chance at SACRIFICE!
        for (int i = row + 1; i < fenWickTree.length; i += (i & -i)) {
            for (int j = col + 1; j < fenWickTree[0].length; j += (j & -j)) {
                fenWickTree[i][j] += diff;
            }
        }
    }
    
    public int sum(int row, int col) {
        int total = 0;
        
        for (int i = row + 1; i > 0; i -= (i & -i)) {
            for (int j = col + 1; j > 0; j -= (j & -j)) {
                total += fenWickTree[i][j];
            }
        }
        
        return total;
    }

    public int sumRegion(int row1, int col1, int row2, int col2) {
        return sum(row2, col2) + sum(row1 - 1, col1 - 1) -
               sum(row1 - 1, col2) - sum(row2, col1 - 1);
    }
}

一刷。
01-Dec-2016

从一维变成二维了。

线段树也能用,小tricky就是用1维坐标表示2维坐标,但是太麻烦。。。

树状数组就好用多了,树状数组对维度的支持性很好,A,B,C,D
这4个点可以当做是原点到A,B,C,D组成的4个矩形,要求的面积就是D-B-C+A这种。

Time:
buiild: O(MNlgNlgM) update: O(lg(mn)) query: O(lg(mn))

public class NumMatrix {
    int[][] nums;
    int[][] tree;
    int m;
    int n;
    
    public NumMatrix(int[][] matrix) {
        if (matrix.length == 0) return;
        this.m = matrix.length;
        this.n = matrix[0].length;
        this.nums = new int[m][n];
        this.tree = new int[m+1][n+1];
        
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                update(i, j, matrix[i][j]);
            }
        }
    }

    public void update(int row, int col, int val) {
        int diff = val - nums[row][col];
        nums[row][col] = val;
        for (int i = row + 1; i <= m; i += (i & -i)) {
            for (int j = col + 1; j <= n; j += (j & -j)) {
                tree[i][j] += diff;
            }
        }
    }
    
    public int getSum(int row, int col) {
        int res = 0;
        for (int i = row; i > 0; i -= (i & -i)) {
            for (int j = col; j > 0; j -= (j & -j)) {
                res += tree[i][j];
            }
        }
        return res;
        
    }

    public int sumRegion(int row1, int col1, int row2, int col2) {
        return getSum(row2+1, col2+1) - getSum(row2+1, col1) -
               getSum(row1, col2+1) + getSum(row1, col1);
    }
}
原文地址:https://www.cnblogs.com/reboot329/p/6121535.html