美文网首页
Leetcode-307Range Sum Query - Mu

Leetcode-307Range Sum Query - Mu

作者: LdpcII | 来源:发表于2018-04-27 02:06 被阅读0次

    307. Range Sum Query - Mutable

    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:

    1. The array is only modifiable by the update function.
    2. You may assume the number of calls to update and sumRange function is distributed evenly.

    My Solution:

    class Segment_tree:
        def build_Segment_tree(self, pos, left, right, value, nums):
            if left == right:
                value[pos] = nums[left]
                return
            mid = (left + right) // 2
            self.build_Segment_tree(2 * pos + 1, left, mid, value, nums)
            self.build_Segment_tree(2 * pos + 2, mid + 1, right, value, nums)
            value[pos] = value[2 * pos + 1] + value[2 * pos + 2]
    
        def sumRange_Segment_tree(self, pos, left, right, qleft, qright, value, nums):
    
            if qleft <= left and qright >= right:  # 区间被[qleft, qright]所覆盖
                return value[pos]
            if qleft > right or qright < left:
                return 0
            mid = (left + right) // 2
            return self.sumRange_Segment_tree(pos * 2 + 1, left, mid, qleft, qright, value, nums) + self.sumRange_Segment_tree(pos * 2 + 2, mid + 1, right, qleft, qright, value, nums)
        
        def update__Segment_tree(self, pos, i, left, right, value, val, nums):
            if left == right and left == i:
                # if pos == i:
                #     value[pos] = val
                # else:
                value[pos] = val
                return
            mid = (left + right) // 2
            if i <= mid:
                self.update__Segment_tree(2 * pos + 1, i, left, mid, value, val, nums)
            else:
                self.update__Segment_tree(2 * pos + 2, i, mid + 1, right, value, val, nums)
            value[pos] = value[2 * pos + 1] + value[2 * pos + 2]
    
    
    class NumArray:
    
        def __init__(self, nums):
            """
            :type nums: List[int]
            """
            self.value = [0 for i in range(4 * len(nums))]  # 线段树通常开数组长度 n 的 4 倍空间4 * n
            self.nums = nums
            if self.nums:
                Segment_tree().build_Segment_tree(0, 0, len(nums) - 1, self.value, self.nums)
    
        def update(self, i, val):
            """
            :type i: int
            :type val: int
            :rtype: void
            """
            Segment_tree().update__Segment_tree(0, i, 0, len(self.nums) - 1, self.value, val, self.nums)
    
        def sumRange(self, i, j):
            """
            :type i: int
            :type j: int
            :rtype: int
            """
            return Segment_tree().sumRange_Segment_tree(0, 0, len(self.nums) - 1, i, j, self.value, self.nums)
    
    # Your NumArray object will be instantiated and called as such:
    # obj = NumArray(nums)
    # obj.update(i,val)
    # param_2 = obj.sumRange(i,j)
    
    

    Reference 1:

    说明:

    Use self.c to represent Binary Indexed Tree.
    Section sums are stored in self.c[1..len(nums)]. x & -x is lowbit function,
    which will return x's rightmost bit 1, e.g. lowbit(7) = 1, lowbit(20) = 4.


    self.c[1] = nums[0]
    self.c[2] = nums[0] + nums[1]
    self.c[3] = nums[2]
    self.c[4] = nums[0] + nums[1] + nums[2] + nums[3]
    self.c[5] = nums[4]
    self.c[6] = nums[4] + nums[5]
    self.c[7] = nums[6]
    self.c[8] = nums[0] + nums[1] + nums[2] + nums[3] + nums[4] + nums[5] + nums[6] + nums[7]


    class NumArray(object):
        def __init__(self, nums):
            self.n = len(nums)
            self.a, self.c = nums, [0] * (self.n + 1)
            for i in range(self.n):
                k = i + 1
                while k <= self.n:
                    self.c[k] += nums[i]
                    k += (k & -k)
    
        def update(self, i, val):
            diff, self.a[i] = val - self.a[i], val
            i += 1
            while i <= self.n:
                self.c[i] += diff
                i += (i & -i)
    
        def sumRange(self, i, j):
            res, j = 0, j + 1
            while j:
                res += self.c[j]
                j -= (j & -j)
            while i:
                res -= self.c[i]
                i -= (i & -i)
            return res
    
    

    Reference 2:

    class NumArray(object):
        def __init__(self, nums):
            self.update = nums.__setitem__
            self.sumRange = lambda i, j: sum(nums[i:j+1])
    
    

    相关文章

      网友评论

          本文标题:Leetcode-307Range Sum Query - Mu

          本文链接:https://www.haomeiwen.com/subject/ltbvlftx.html