LeetCode-307. Range Sum Query - Mutable [C++][Java]

Loading...Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.https://leetcode.com/problems/range-sum-query-mutable/

Given an integer array nums, handle multiple queries of the following types:

  1. Update the value of an element in nums.
  2. Calculate the sum of the elements of nums between indices left and right inclusive where left <= right.

Implement the NumArray class:

  • NumArray(int[] nums) Initializes the object with the integer array nums.
  • void update(int index, int val) Updates the value of nums[index] to be val.
  • int sumRange(int left, int right) Returns the sum of the elements of nums between indices left and right inclusive (i.e. nums[left] + nums[left + 1] + ... + nums[right]).

Example 1:

Input
["NumArray", "sumRange", "update", "sumRange"]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
Output
[null, 9, null, 8]

Explanation
NumArray numArray = new NumArray([1, 3, 5]);
numArray.sumRange(0, 2); // return 1 + 3 + 5 = 9
numArray.update(1, 2);   // nums = [1, 2, 5]
numArray.sumRange(0, 2); // return 1 + 2 + 5 = 8

Constraints:

  • 1 <= nums.length <= 3 * 10^4
  • -100 <= nums[i] <= 100
  • 0 <= index < nums.length
  • -100 <= val <= 100
  • 0 <= left <= right < nums.length

【C++】

借用线段树:用来查询某一区间对应的信息(如最大值,最小值,区间和等)。

class NumArray {
    vector<int> tree; // segment tree
    int n;
public:
    NumArray(vector<int>& nums) {
        n = nums.size();
        tree = vector<int>(n*2);
        for (int i = 2*n-1; i >= n; i--) {tree[i] = nums[i-n];}
        for (int i = n-1; i > 0; i--) {tree[i] = tree[2*i] + tree[2*i+1];}
    }
    
    void update(int index, int val) {
        index += n;
        tree[index] = val;
        while (index > 1) {
            index >>= 1;
            int newval = tree[2*index] + tree[2*index+1];
            if (tree[index] == newval) {return;}
            tree[index] = newval;
        }
    }
    
    int sumRange(int left, int right) {
        left += n;
        right += n + 1;
        int sum = 0;
        while(left < right) {
            if (left&1 == 1) {sum += tree[left++];}
            if (right&1 == 1) {sum += tree[--right];}
            left >>= 1;
            right >>= 1;
        }
        return sum;
    }
};

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

【Java】

class NumArray {
    private int[] tree; // segment tree
    private int n;

    public NumArray(int[] nums) {
        n = nums.length;
        tree = new int[n*2];
        for (int i = 2*n-1; i >= n; i--) {tree[i] = nums[i-n];}
        for (int i = n-1; i > 0; i--) {tree[i] = tree[2*i] + tree[2*i+1];}
    }
    
    public void update(int index, int val) {
        index += n;
        tree[index] = val;
        while (index > 1) {
            index >>= 1;
            int newval = tree[2*index] + tree[2*index+1];
            if (tree[index] == newval) {return;}
            tree[index] = newval;
        }
    }
    
    public int sumRange(int left, int right) {
        left += n;
        right += n + 1;
        int sum = 0;
        while(left < right) {
            if ((left&1) == 1) {sum += tree[left++];}
            if ((right&1) == 1) {sum += tree[--right];}
            left >>= 1;
            right >>= 1;
        }
        return sum;
    }
}

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

参考文献

【1】数据结构与算法(十)线段树(Segment Tree)入门

【2】线段树(segment tree),看这一篇就够了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贫道绝缘子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值