307. 区域和检索 - 数组可修改
方法一:直接数组遍历进行修改与查找
方法二:线段树,以下为线段树代码 主要是为了练习一下线段树模板
class NumArray {
int N = 30001*4;
int[] arr = new int[N];
int[] val = new int[N]; // 记录值
int[] left = new int[N]; // 左节点
int[] right = new int[N]; // 右节点
int[] lz = new int[N];
int len = 0;
int changed;
public NumArray(int[] nums) {
len = nums.length;
build(1,0,nums.length-1,nums);
}
public void update(int index, int val) {
change(1,val,index);
}
public int sumRange(int left, int right) {
return search(1,left,right);
}
public void build(int idx , int l , int r , int nums[]){
left[idx] = l;
right[idx] = r;
if(l==r){
val[idx] = nums[l];
return ;
}
int mid = l+r>>1;
build(idx<<1 , l , mid,nums);
build((idx<<1)+1 , mid + 1, r,nums);
val[idx] = val[idx<<1] + val[(idx<<1)+1];
}
public void change(int idx ,int value,int index){ // 单点修改
if(left[idx] == index && right[idx] == index){
changed = val[idx];
val[idx] = value;
return ;
}
int mid = left[idx] + right[idx] >> 1;
if(index <= mid) change(idx<<1,value,index);
else {
change((idx << 1) + 1, value , index);
}
val[idx] -= changed - value;
}
public int search(int idx , int l , int r){ // 区间查询
if( left[idx] == l && right[idx] == r){
return val[idx];
}
int mid = left[idx] + right[idx] >> 1;
if(r <= mid){
return search(idx<<1,l,r);
}else if(l> mid){
return search((idx<<1)+1,l,r);
}else{
return search(idx<<1, l,mid) + search((idx<<1)+1,mid+1,r);
}
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* obj.update(index,val);
* int param_2 = obj.sumRange(left,right);
*/