Range Sum Query - Mutable

Given an integer array nums, handle multiple queries of the following types:

  1. Update the value of an element in nums.
  2. Calculate the sum of the elements of nums between indices left and right inclusive where left <= right.

Implement the NumArray class:

  • NumArray(int[] nums) Initializes the object with the integer array nums.
  • void update(int index, int val) Updates the value of nums[index] to be val.
  • int sumRange(int left, int right) Returns the sum of the elements of nums between indices left and right inclusive (i.e. nums[left] + nums[left + 1] + ... + nums[right]).

 

Example 1:

Input
["NumArray", "sumRange", "update", "sumRange"]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
Output
[null, 9, null, 8]

Explanation
NumArray numArray = new NumArray([1, 3, 5]);
numArray.sumRange(0, 2); // return 1 + 3 + 5 = 9
numArray.update(1, 2);   // nums = [1, 2, 5]
numArray.sumRange(0, 2); // return 1 + 2 + 5 = 8

 

Constraints:

  • 1 <= nums.length <= 3 * 104
  • -100 <= nums[i] <= 100
  • 0 <= index < nums.length
  • -100 <= val <= 100
  • 0 <= left <= right < nums.length
  • At most 3 * 104 calls will be made to update and sumRange.
SOLUTION:
class Node:
    def __init__(self, start, end, total = 0):
        self.start = start
        self.end = end
        self.left = None
        self.right = None
        self.total = 0

class NumArray:
    def __init__(self, nums):
        n = len(nums)
        self.root = self.createTree(0, n - 1, nums)
        
    def createTree(self, start, end, nums):
        if start > end:
            return None
        root = Node(start, end)
        if start == end:
            root.total = nums[start]
            return root
        mid = (start + end) // 2
        root.left = self.createTree(start, mid, nums)
        root.right = self.createTree(mid + 1, end, nums)
        root.total = root.left.total + root.right.total
        return root
    
    def updateVal(self, root, i, val):
        if not root:
            return
        if root.start == root.end:
            root.total = val
            return
        mid = (root.start + root.end) // 2
        if i <= mid:
            self.updateVal(root.left, i, val)
        elif i >= mid + 1:
            self.updateVal(root.right, i, val)
        root.total = root.left.total + root.right.total
    
    def update(self, index, val):
        self.updateVal(self.root, index, val)
    
    def getSum(self, root, start, end):
        if not root:
            return 0
        if root.start == start and root.end == end:
            return root.total
        mid = (root.start + root.end) // 2
        if end <= mid:
            return self.getSum(root.left, start, end)
        elif start >= mid + 1:
            return self.getSum(root.right, start, end)
        else:
            return self.getSum(root.left, start, mid) + self.getSum(root.right, mid + 1, end)
    
    def sumRange(self, left, right):
        return self.getSum(self.root, left, right)

Comments

Popular posts from this blog

Lazy Deletion in Heap: A Wrapper for Python heapq

Sliding Window GCD

Degree of an Array