zoukankan      html  css  js  c++  java
  • 307. Range Sum Query

    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.

    Accepted
    58,610
    Submissions
    226,522

    Solution1:(TLE)

    class NumArray:
    
        def __init__(self, nums):
            """
            :type nums: List[int]
            """
            self.nums = nums
            if len(nums)>0:
                self.sum = [nums[0]]
                for i in range(1,len(nums)):
                    self.sum.append(self.sum[-1] + nums[i])
    
        def update(self, i, val):
            """
            :type i: int
            :type val: int
            :rtype: void
            """
            diff = val - self.nums[i]
            self.nums[i] = val
            for i in range(i,len(self.nums)):
                self.sum[i] += diff
            return
    
        def sumRange(self, i, j):
            """
            :type i: int
            :type j: int
            :rtype: int
            """
            return self.sum[j] - self.sum[i] + self.nums[i]
    
    # Your NumArray object will be instantiated and called as such:
    # obj = NumArray(nums)
    # obj.update(i,val)
    # param_2 = obj.sumRange(i,j)
    

    9 / 10 test cases passed.

    Solution2:

    """
        The idea here is to build a segment tree. Each node stores the left and right
        endpoint of an interval and the sum of that interval. All of the leaves will store
        elements of the array and each internal node will store sum of leaves under it.
        Creating the tree takes O(n) time. Query and updates are both O(log n).
    """
    
    
    # Segment tree node
    class Node(object):
        def __init__(self, start, end):
            self.start = start
            self.end = end
            self.total = 0
            self.left = None
            self.right = None
    
    
    class NumArray(object):
        def __init__(self, nums):
            """
            initialize your data structure here.
            :type nums: List[int]
            """
    
            # helper function to create the tree from input array
            def createTree(nums, l, r):
    
                # base case
                if l > r:
                    return None
    
                # leaf node
                if l == r:
                    n = Node(l, r)
                    n.total = nums[l]
                    return n
    
                mid = (l + r) // 2
    
                root = Node(l, r)
    
                # recursively build the Segment tree
                root.left = createTree(nums, l, mid)
                root.right = createTree(nums, mid + 1, r)
    
                # Total stores the sum of all leaves under root
                # i.e. those elements lying between (start, end)
                root.total = root.left.total + root.right.total
    
                return root
    
            self.root = createTree(nums, 0, len(nums) - 1)
    
        def update(self, i, val):
            """
            :type i: int
            :type val: int
            :rtype: int
            """
    
            # Helper function to update a value
            def updateVal(root, i, val):
    
                # Base case. The actual value will be updated in a leaf.
                # The total is then propogated upwards
                if root.start == root.end:
                    root.total = val
                    return val
    
                mid = (root.start + root.end) // 2
    
                # If the index is less than the mid, that leaf must be in the left subtree
                if i <= mid:
                    updateVal(root.left, i, val)
    
                # Otherwise, the right subtree
                else:
                    updateVal(root.right, i, val)
    
                # Propogate the changes after recursive call returns
                root.total = root.left.total + root.right.total
    
                return root.total
    
            return updateVal(self.root, i, val)
    
        def sumRange(self, i, j):
            """
            sum of elements nums[i..j], inclusive.
            :type i: int
            :type j: int
            :rtype: int
            """
    
            # Helper function to calculate range sum
            def rangeSum(root, i, j):
    
                # If the range exactly matches the root, we already have the sum
                if root.start == i and root.end == j:
                    return root.total
    
                mid = (root.start + root.end) // 2
    
                # If end of the range is less than the mid, the entire interval lies
                # in the left subtree
                if j <= mid:
                    return rangeSum(root.left, i, j)
    
                # If start of the interval is greater than mid, the entire inteval lies
                # in the right subtree
                elif i >= mid + 1:
                    return rangeSum(root.right, i, j)
    
                # Otherwise, the interval is split. So we calculate the sum recursively,
                # by splitting the interval
                else:
                    return rangeSum(root.left, i, mid) + rangeSum(root.right, mid + 1, j)
    
            return rangeSum(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)
    
  • 相关阅读:
    Matlab2018 b 下载和安装激活说明
    亿图思维导图软件 Edraw MindMaster Pro 8.0.102 中文直装版全功能专业版
    中华人民共和国民法典全文及下载
    qbxt DAY3 T4
    洛谷P1972 [SDOI2009]HH的项链——题解
    洛谷P2824 [HEOI2016/TJOI2016]排序——题解
    洛谷P1966 火柴排队——题解
    逆序对小记(~dtk)
    0/1分数规划 小记
    洛谷P3199 [HNOI2009]最小圈——题解
  • 原文地址:https://www.cnblogs.com/bernieloveslife/p/10050981.html
Copyright © 2011-2022 走看看