最后更新
二刷。
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);
}
}