Back
Featured image of post NumArray307

NumArray307

Leetcode-307

Leetcode 307

这是今天做的一个题 307. 区域和检索 - 数组可修改

303. 区域和检索 - 数组不可变 不同的是 数组可修改

上一个dalao的分析 , 放弃996了

/**
 * 数组不变,求区间和:「前缀和」、「树状数组」、「线段树」
 *
 * 多次修改某个数,求区间和:「树状数组」、「线段树」
 *
 * 多次整体修改某个区间,求区间和:「线段树」、「树状数组」(看修改区间的数据范围)
 *
 * 多次将某个区间变成同一个数,求区间和:「线段树」、「树状数组」(看修改区间的数据范围)
 *
 */

学了个树状数组方法。

class NumArray {
    int[] tree;

    int lowBits(int x){
        return x & -x;//保留二进制下最后出现的1的位置,其余位置置0
    }
    //当一个偶数与它的负值向与时,结果是能被这个偶数整除的最大的2的n次幂 , 比如10返回2
    //当一个奇数与它的负值向与时结果一定是1

    // 查询前缀和的方法
    int query(int x){
        int ans = 0;
        for (int i = x; i > 0 ; i -= lowBits(i)) {
            ans += tree[i];
        }
        return ans;
    }

    // 在树状数组 x 位置中增加值 u
    void add(int x ,int u){
        for (int i = x; i <= n ; i += lowBits(i)) {
            tree[i] += u;
        }
    }

    int[] nums;
    int n;

    // 初始化「树状数组」
    public NumArray(int[] nums) {
        this.nums = nums;
        n = nums.length;
        tree = new int[n + 1];
        for (int i = 0; i < n; i++) {
            add(i + 1, nums[i]);
        }
    }

    // 原有的值是 nums[i],要使得修改为 val,需要增加 val - nums[i]
    public void update(int index, int val) {
        add(index + 1 , val - nums[index]);
        nums[index] = val;
    }

    public int sumRange(int left, int right) {
        return query(right + 1) - query(left);
    }
}
Welcome to the world of Minezeratul