LeetCode[307]Range Sum Query - Mutable(Java)

Description:

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

The  update(i, val)  function modifies  nums  by updating the element at index  i  to  val .

Example:

Given nums = [1, 3, 5]

sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8

Note:

  1. The array is only modifiable by the update function.
  2. You may assume the number of calls to update and sumRange function is distributed evenly.

树状数组:
已知数组A[ ],则建立树状数组C[ ],则C[ ]满足:
C1 = A1
C2 = A1 + A2
C3 = A3
C4 = A1 + A2 + A3 + A4
C5 = A5
C6 = A5 + A6
C7 = A7
C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
...
C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16
当想要查询一个SUM(n )(求a[n]的和),可以依据如下算法即可:
step1: 令sum = 0,转第二步;
step2: 假如n <= 0,算法结束,返回sum值,否则sum = sum + C[n],转第三步;
step3: 令n = n – lowbit(n),转第二步。
可以看出,这个算法就是将这一个个区间的和全部加起来,效率是log(n).
设节点编号为x,那么这个节点管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。因为这个区间最后一个元素必然为Ax,
所以很明显:C[n] = A[n – 2^k + 1]+ ... + A[n]
Solution:
/*
solution: TreeArray
          O(n) = log(n);
*/
class NumArray {
    int length = 0;
    int[] tree;
    int[] nums;
    
    public NumArray(int[] nums) {
        this.nums = nums;
        length = nums.length;
        tree = new int[length + 1];
        tree[0] = 0;
        //initial the Tree Array
        for(int i = 1;i<=length;i++){
            int count = lowBit(i);
            int sum = 0;
            while(count > 0){
                sum += nums[i - count];
                count--;
            }
            tree[i] = sum;
        }
    }
    
    public void update(int i, int val) {
        int gap = val - nums[i];
        nums[i] = val;
        int count = i + 1;
        
        while(count <= length){
            tree[count] += gap;
            count += lowBit(count);
        }
    }
    
    public int sumRange(int i, int j) {
        return sum(j + 1) - sum(i);
    }
    //calculate the interval contained by the tree[i]
    public int lowBit(int i){
        return i & (-i);
    }
    //calculate the sun of interval that starts with 0 and end with index
    public int sum(int i){
        int result = 0;
        int current = i;
        while(current > 0){
            result += tree[current];
            current -= lowBit(current);
        }
        return result;
    }
}

/**
 * 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);
 */






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值