LeetCode 307
class NumArray {
int[] sum;
int size;
int[] nums;
public NumArray(int[] nums) {
if (nums == null || nums.length == 0)
return;
this.nums = nums;
this.size = nums.length;
sum = new int[4*size];
buildTree(1, 0, size - 1);
}
private void buildTree(int nodeId, int left, int right) {
if (left == right) {
sum[nodeId] = nums[left]; // += 改成 =
return;
}
int mid = (left + right) >> 1;
buildTree(nodeId << 1 , left, mid);
buildTree(nodeId << 1|1 , mid + 1, right);
sum[nodeId] = sum[nodeId << 1] + sum[nodeId << 1|1];
}
public void update(int i, int val) {
updateSingle(1, val, i, 0, size - 1);
}
private void updateSingle(int nodeId, int val, int leftRight, int left, int right) {
if (left == right) {
nums[left] = val;
sum[nodeId] = val;
return;
}
int mid = (left + right) >> 1;
if (leftRight <= mid && leftRight >= left)
updateSingle(nodeId << 1, val, leftRight, left, mid);
else
updateSingle(nodeId << 1 | 1, val, leftRight, mid + 1, right);
sum[nodeId] = sum[nodeId << 1] + sum[nodeId << 1|1];
}
public int sumRange(int i, int j) {
return query(1, i, j, 0, size - 1);
}
private int query(int nodeId, int qLeft, int qRight, int left, int right) {
if (qLeft == qRight) return nums[qLeft];
if (qRight < left || qLeft > right) return 0; //超出范围!
if (qLeft <= left && qRight >= right){
return sum[nodeId];
}
int mid = (left + right) >> 1;
int lVal = query(nodeId << 1, qLeft, qRight, left, mid);
int rVal = query(nodeId << 1|1, qLeft, qRight, mid + 1, right);
return lVal + rVal;
}
}
/**
* 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);
*/