Fenwick Tree 307
对于一个数组 arr[1...n]
,Fenwick Tree 可以支持两种操作:
-
update(i, delta)
:将arr[i] += delta
-
query(i)
:返回前缀和arr[1] + arr[2] + ... + arr[i]
它的时间复杂度为:
-
构建:
O(n)
-
查询:
O(log n)
-
更新:
O(log n)
1 # 注意,这里实现的时候,默认下表从1开始,因此实际使用时传入下标要+1 2 class FenwickTree: 3 def __init__(self, n): 4 self._sums = [0 for _ in range(n + 1)] 5 6 def update(self, i, delta): 7 while i < len(self._sums): 8 self._sums[i] += delta 9 i += i & -i 10 11 def query(self, i): 12 s = 0 13 while i > 0: 14 s += self._sums[i] 15 i -= i & -i 16 return s
Given an integer array nums
, handle multiple queries of the following types:
- Update the value of an element in
nums
. - Calculate the sum of the elements of
nums
between indicesleft
andright
inclusive whereleft <= right
.
Implement the NumArray
class:
NumArray(int[] nums)
Initializes the object with the integer arraynums
.void update(int index, int val)
Updates the value ofnums[index]
to beval
.int sumRange(int left, int right)
Returns the sum of the elements ofnums
between indicesleft
andright
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 * 104
-100 <= nums[i] <= 100
0 <= index < nums.length
-100 <= val <= 100
0 <= left <= right < nums.length
- At most
3 * 104
calls will be made toupdate
andsumRange
.
class NumArray: def __init__(self, nums: List[int]): self.tree = FenwickTree(len(nums)) self.nums = nums for i in range(len(nums)): self.tree.update(i + 1, nums[i]) def update(self, index: int, val: int) -> None: self.tree.update(index + 1, val - self.nums[index]) self.nums[index] = val def sumRange(self, left: int, right: int) -> int: return self.tree.query(right + 1) - self.tree.query(left) # 注意,这里实现的时候,默认下表从1开始,因此实际使用时传入下标要+1 class FenwickTree: def __init__(self, n): self._sums = [0 for _ in range(n + 1)] def update(self, i, delta): while i < len(self._sums): self._sums[i] += delta i += i & -i def query(self, i): s = 0 while i > 0: s += self._sums[i] i -= i & -i return s # Your NumArray object will be instantiated and called as such: # obj = NumArray(nums) # obj.update(index,val) # param_2 = obj.sumRange(left,right)