- 所有题, Immutable的题用prefix sum,Mutable的题用Segment Tree
303. Range Sum Query - Immutable
304. Range Sum Query 2D - Immutable
307. Range Sum Query - Mutable
308. Range Sum Query 2D - Mutable
303. Range Sum Query - Immutable
1-D prefix sum
304. Range Sum Query 2D - Immutable
2D_range_sum.jpeg
class NumMatrix {
//pre[i][j] is the sum of rectangle from (0, 0) to (i-1, j-1)
int[][] pre;
public NumMatrix(int[][] matrix) {
if (matrix.length == 0 || matrix[0].length == 0) return;
int m = matrix.length, n = matrix[0].length;
pre = new int[m+1][n+1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + matrix[i-1][j-1];
}
}
}
public int sumRegion(int r1, int c1, int r2, int c2) {
//(r1, c1) (r1, c2)
//(r2, c1) (r2, c2)
return pre[r2+1][c2+1] - pre[r1][c2+1] - pre[r2+1][c1] + pre[r1][c1];
}
}
307. Range Sum Query - Mutable
SegmentTree_1.jpeg
SegmentTree_2.jpeg
class NumArray {
class STNode {
int begin, end, sum;
STNode left, right;
public STNode(int begin, int end, int sum) {
this.begin = begin;
this.end = end;
this.sum = sum;
}
}
class SegmentTree {
STNode root;
public SegmentTree(int[] nums) {
root = build(0, nums.length-1, nums);
}
public STNode build(int begin, int end, int[] nums) {
if (begin == end) {
return new STNode(begin, end, nums[begin]);
}
int mid = begin + (end - begin) / 2;
STNode left = build(begin, mid, nums);
STNode right = build(mid + 1, end, nums);
STNode root = new STNode(begin, end, left.sum + right.sum);
root.left = left;
root.right = right;
return root;
}
public void update(STNode root, int index, int val) { //update a leave
if (root.begin == root.end && root.begin == index) {
root.sum = val;
return;
}
int mid = root.begin + (root.end - root.begin) / 2;
//如果index小于等于mid,leaf to be updated is in the left sub tree
//else, it is in the right sub tree
if (index <= mid) {
update(root.left, index, val);
} else {
update(root.right, index, val);
}
root.sum = (root.left == null ? 0 : root.left.sum) +
(root.right == null ? 0 : root.right.sum);
}
public int query(STNode root, int i, int j) {
if (root.begin == i && root.end == j) {
return root.sum;
}
int mid = root.begin + (root.end - root.begin) / 2;
if (j <= mid) {
return query(root.left, i, j);
} else if (i >= mid+1) {
return query(root.right, i, j);
} else {
return query(root.left, i, mid) + query(root.right, mid + 1, j);
}
}
}
SegmentTree st;
public NumArray(int[] nums) {
if (nums == null || nums.length == 0) return;
st = new SegmentTree(nums);
}
public void update(int i, int val) {
st.update(st.root, i, val);
}
public int sumRange(int i, int j) {
return st.query(st.root, i, j);
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* obj.update(i,val);
* int param_2 = obj.sumRange(i,j);
*/