307. Range Sum Query

来源:互联网 发布:长沙网络推广 编辑:程序博客网 时间:2024/06/06 12:19

原题:

Given an integer array nums, find the sum of the elements between indicesi and j (ij), inclusive.

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

Example:

Given nums = [1, 3, 5]sumRange(0, 2) -> 9update(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.

主要实现功能是给数组下标范围,返回它的该范围内元素的和。


解题思路:硬解O(n)是TLE的。这里用到一个新的数据结构叫树状数组。它是一个修改元素和查询元素复杂度都是O(logn)的数组。它的原理不好理解,我也没弄清。它主要有三个方法,我暂时会用:

public int sumRange(int i, int j) {        return sum(j + 1) - sum(i);    }    int lowbit(int pos){        return pos&(-pos);    }        void add(int pos, int value){//修改元素值        while(pos < c.length){            c[pos] += value;            pos += lowbit(pos);        }    }        int sum(int pos){//返回前i个元素和        int res = 0;        while(pos > 0){            res += c[pos];            pos -= lowbit(pos);        }        return res;    }

树状数组一般都是辅助用的数组,用于把你需要操作的数组以另一种形式存起来。


结果代码:

int[]c;    int[]nums;    public NumArray(int[] nums) {        this.nums = nums;        int len = nums.length;        c = new int[len + 1];        for (int i = 0;i < len;i++){            add(i + 1,nums[i]);        }    }    public void update(int i, int val) {        int dif = val - nums[i];        nums[i] = val;        add(i + 1,dif);    }    public int sumRange(int i, int j) {        return sum(j + 1) - sum(i);    }    int lowbit(int pos){        return pos&(-pos);    }    void add(int pos, int value){//修改元素值        while(pos < c.length){            c[pos] += value;            pos += lowbit(pos);        }    }    int sum(int pos){//返回前i个元素和        int res = 0;        while(pos > 0){            res += c[pos];            pos -= lowbit(pos);        }        return res;    }