题目描述:
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.
The update(i, val) function modifies nums by updating the element at index i to val.
Example:
Given nums = [1, 3, 5] sumRange(0, 2) -> 9 update(1, 2) sumRange(0, 2) -> 8
Note:
- The array is only modifiable by the update function.
- You may assume the number of calls to update and sumRange function is distributed evenly.
题目大意:
给定一个整数数组nums,计算下标i与j之间的元素和(i ≤ j),包含边界。
函数update(i, val)将位于下标i的元素值修改为val。
测试用例见题目描述。
注意:
- 数组只能通过update函数修改。
- 你可以假设update函数与sumRange函数的调用次数是均匀分布的。
解题思路:
解法I:线段树(Segment Tree)的基础应用
参考博文:http://bookshadow.com/weblog/2015/08/13/segment-tree-set-1-sum-of-given-range/
Python代码:
class NumArray(object):
def __init__(self, nums):
"""
initialize your data structure here.
:type nums: List[int]
"""
self.nums = nums
self.size = size = len(nums)
h = int(math.ceil(math.log(size, 2))) if size else 0
maxSize = 2 ** (h + 1) - 1
self.st = [0] * maxSize
if size:
self.initST(0, size - 1, 0)
def update(self, i, val):
"""
:type i: int
:type val: int
:rtype: int
"""
if i < 0 or i >= self.size:
return
diff = val - self.nums[i]
self.nums[i] = val
self.updateST(0, self.size - 1, i, diff, 0)
def sumRange(self, i, j):
"""
sum of elements nums[i..j], inclusive.
:type i: int
:type j: int
:rtype: int
"""
if i < 0 or j < 0 or i >= self.size or j >= self.size:
return 0
return self.sumRangeST(0, self.size - 1, i, j, 0)
def initST(self, ss, se, si):
if ss == se:
self.st[si] = self.nums[ss]
else:
mid = (ss + se) / 2
self.st[si] = self.initST(ss, mid, si * 2 + 1) + \
self.initST(mid + 1, se, si * 2 + 2)
return self.st[si]
def updateST(self, ss, se, i, diff, si):
if i < ss or i > se:
return
self.st[si] += diff
if ss != se:
mid = (ss + se) / 2
self.updateST(ss, mid, i, diff, si * 2 + 1)
self.updateST(mid + 1, se, i, diff, si * 2 + 2)
def sumRangeST(self, ss, se, qs, qe, si):
if qs <= ss and qe >= se:
return self.st[si]
if se < qs or ss > qe:
return 0
mid = (ss + se) / 2
return self.sumRangeST(ss, mid, qs, qe, si * 2 + 1) + \
self.sumRangeST(mid + 1, se, qs, qe, si * 2 + 2)
# Your NumArray object will be instantiated and called as such:
# numArray = NumArray(nums)
# numArray.sumRange(0, 1)
# numArray.update(1, 10)
# numArray.sumRange(1, 2)
解法II:树状数组(Binary Indexed Tree / Fenwick Tree)
参考博文:http://www.hrwhisper.me/leetcode-range-sum-query-mutable/
Python代码:
class NumArray(object):
def __init__(self, nums):
"""
initialize your data structure here.
:type nums: List[int]
"""
self.sums = [0] * (len(nums) + 1)
self.nums = nums
self.n = len(nums)
for i in xrange(len(nums)):
self.add(i + 1,nums[i])
def add(self,x,val):
while x <= self.n:
self.sums[x] += val
x += self.lowbit(x)
def lowbit(self,x):
return x & -x
def sum(self,x):
res = 0
while x > 0:
res += self.sums[x]
x -= self.lowbit(x)
return res
def update(self, i, val):
"""
:type i: int
:type val: int
:rtype: int
"""
self.add(i + 1, val - self.nums[i])
self.nums[i] = val
def sumRange(self, i, j):
"""
sum of elements nums[i..j], inclusive.
:type i: int
:type j: int
:rtype: int
"""
if not self.nums:
return 0
return self.sum(j+1) - self.sum(i)
# Your NumArray object will be instantiated and called as such:
# numArray = NumArray(nums)
# numArray.sumRange(0, 1)
# numArray.update(1, 10)
# numArray.sumRange(1, 2)
本文链接:http://bookshadow.com/weblog/2015/11/18/leetcode-range-sum-query-mutable/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。