307. 区域和检索 - 数组可修改
给你一个数组
nums
,请你完成两类查询。- 其中一类查询要求 更新 数组
nums
下标对应的值
- 另一类查询要求返回数组
nums
中索引left
和索引right
之间( 包含 )的nums元素的 和 ,其中left <= right
实现
NumArray
类:NumArray(int[] nums)
用整数数组nums
初始化对象
void update(int index, int val)
将nums[index]
的值 更新 为val
int sumRange(int left, int right)
返回数组nums
中索引left
和索引right
之间( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], ..., nums[right]
)
示例 1:
输入: ["NumArray", "sumRange", "update", "sumRange"] [[[1, 3, 5]], [0, 2], [1, 2], [0, 2]] 输出: [null, 9, null, 8] 解释: NumArray numArray = new NumArray([1, 3, 5]); numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9 numArray.update(1, 2); // nums = [1,2,5] numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
提示:
1 <= nums.length <= 3 * 10
4
100 <= nums[i] <= 100
0 <= index < nums.length
100 <= val <= 100
0 <= left <= right < nums.length
- 调用
update
和sumRange
方法次数不大于3 * 10
4
模板题
思路
标准的树状数组模板题目
题解
class NumArray: def lowbit(self, x): return x & (-x) def __init__(self, nums: List[int]): # 原数组 self.nums = nums # 树状数组 self.tree = [0] * (len(self.nums) + 1) # 构建树状数组 for i in range(1, len(self.tree)): self.tree[i] += self.nums[i-1] # i + self.lowbit(i) 为 父节点的下标 # 父节点 = nums的值 + 子节点的值 if i + self.lowbit(i) < len(self.tree): self.tree[i + self.lowbit(i)] += self.tree[i] def update(self, index: int, val: int) -> None: # 如果相同就不用改了 if val == self.nums[index]: return i = index + 1 delta = val - self.nums[index] while i < len(self.tree): self.tree[i] += delta i += self.lowbit(i) # 修改原数组 self.nums[index] = val def prefix(self, index): i = index + 1 sum_ = 0 while i > 0: sum_ += self.tree[i] i -= self.lowbit(i) return sum_ def sumRange(self, left: int, right: int) -> int: return self.prefix(right) - self.prefix(left-1) # Your NumArray object will be instantiated and called as such: # obj = NumArray(nums) # obj.update(index,val) # param_2 = obj.sumRange(left,right)