边工作边刷题:70天一遍leetcode: day 31-3

Range Sum Query - Mutable

要点:一道segment tree题,segment tree的结构要点是完全binary tree的下一层二分上一层的区间。对于这道题,要实现buildTree, sumQuery和update methods。

  • buildTree: 注意叶结点实际存的是单个元素,所以这是一个post-order的bottom up构建。累加左右子树的结果并返回。创建root在最后,所以别忘了连接左右子树
  • sumQuery:query实际是一个区间比较和累加的过程(这个无论是sum还是minimum query都是一样的):segment tree的结点本身的区间和查询区间的比较,如果tree range在query range范围内,得到一个有效累加结果返回。如果overlapping,继续向左右子树查找:注意,查询区间是不变的。因为叶子是单个元素,所以总会找到全部有效区间
  • update:一个错误是更新输入数组本身:因为在buildTree的时候已经把单个元素信息存在叶子结点了,所以更新叶子结点,并重新计算受影响的上层结点即可(这个和buildTree的过程是一样的,唯一差别就是更新结点不在区间,直接返回区间当前值即可)

错误点:(EDIT:4/23/16)

  • 因为上层要重新计算和,update不在范围内要返回当前Node的val,而不是0。
class NumArray(object):
    class _TreeNode(object):
        def __init__(self, l, h, val):
            self.l=l
            self.h=h
            self.val=val
            self.left=None
            self.right=None
    
    def __init__(self, nums):
        """
        initialize your data structure here.
        :type nums: List[int]
        """
        def build(nums, i, j):
            if i>j: return None
            if i==j: return self._TreeNode(i,i,nums[i])
            
            m = i+(j-i)/2
            left = build(nums, i, m)
            right = build(nums, m+1, j)
            sum = 0
            if left:
                sum+=left.val
            if right:
                sum+=right.val
            root = self._TreeNode(i,j,sum)
            root.left = left
            root.right = right
            return root
        
        self.root = build(nums, 0, len(nums)-1)

    def update(self, i, val):
        """
        :type i: int
        :type val: int
        :rtype: int
        """
        def updateRec(root, i, val):
            if i>root.h or i<root.l:
                return root.val
            
            if root.l==root.h and root.l==i:
                root.val = val
                return root.val
                
            leftv,rightv=0,0
            if root.left:
                leftv = updateRec(root.left, i, val)
            if root.right:
                rightv = updateRec(root.right, i, val)
            root.val = leftv+rightv
            return root.val
            
        updateRec(self.root, i, val)

    def sumRange(self, i, j):
        """
        sum of elements nums[i..j], inclusive.
        :type i: int
        :type j: int
        :rtype: int
        """
        def queryRec(root, i, j):
            if i<=root.l and j>=root.h:
                return root.val
            
            if i>root.h or j<root.l:
                return 0
            
            leftv,rightv = 0,0
            if root.left:
                leftv = queryRec(root.left, i, j)
                
            if root.right:
                rightv = queryRec(root.right, i, j)
        
            return leftv+rightv
            
        return queryRec(self.root, i, j)

# 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)
原文地址:https://www.cnblogs.com/absolute/p/5678135.html