array
bit
segment tree
]
Leetcode 0307. Range Sum Query - Mutable
Problem statement
https://leetcode.com/problems/range-sum-query-mutable/
Solution
There are two classical way how you can solve this problem: segment trees or binary indexed trees. The second one is easier to code. For more definition of BIT, see wikipedia: https://en.wikipedia.org/wiki/Fenwick_tree
Here we need not to update value by delta
as it is done in classical implementation, but replace number. So we need to keep both BIT and original array: we keep self.bit
: our tree and self.nums
our nums. When we do initialization, here I do it not in optimal way: we update number by number in our BIT
: so total complexity of initialization will be O(n log n)
- there exists also O(n)
way to do it, but it is more difficult to code. Inside function update
we update both BIT and self.nums
. Finally, to evaluate sumRange
, we apply two times query
: query(x)
returns sum of first x
elements.
Complexity
Space complexity is O(n)
for whole data structure. Time complexity of initialization is O(n log n)
, time complexity of update
and sumRange
is O(log n)
.
Code
class BIT:
def __init__(self, n):
self.sums = [0] * (n+1)
def update(self, i, delta):
while i < len(self.sums):
self.sums[i] += delta
i += i & (-i)
def query(self, i):
res = 0
while i > 0:
res += self.sums[i]
i -= i & (-i)
return res
class NumArray:
def __init__(self, nums):
self.bit = BIT(len(nums))
for i, num in enumerate(nums):
self.bit.update(i+1, num)
self.nums = [0] + nums
def update(self, i, val):
self.bit.update(i+1, val - self.nums[i+1])
self.nums[i+1] = val
def sumRange(self, i, j):
return self.bit.query(j+1) - self.bit.query(i)