본문 바로가기
카테고리 없음

[LeetCode with Python] 307. Range Sum Query

by papajohns 2020. 7. 4.

Difficulty : Medium

 

Approach 1 : use array and update, sum with index

 

class NumArray:

    def __init__(self, nums: List[int]):
        self.nums = nums
    
    def update(self, i: int, val: int) -> None:
        self.nums[i] = val
        

    def sumRange(self, i: int, j: int) -> int:
        return sum(self.nums[i:j+1])
        


# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# obj.update(i,val)
# param_2 = obj.sumRange(i,j)

 

Approach 2 : use segment tree. but memory limit exceeded error now :(

 

from typing import List

class NumArray:

    def __init__(self, nums: List[int]):
        self.nums = nums
        self.tree = [0] * (3 * len(nums))
        self.tree_init(0, len(nums) - 1, 1)
        #print(self.tree)

        
    def tree_init(self, start: int, end: int, node: int) -> int:
        if start == end:
            #print(node, start, end)
            self.tree[node] = self.nums[start]
            return self.tree[node]
        mid = (start + end) // 2
        self.tree[node] = self.tree_init(start, mid, node * 2) + self.tree_init(mid + 1, end, node * 2 + 1)
        return self.tree[node]
    
    def update_(self, start: int, end: int, node: int, index: int, dif: int) -> None:
        if index < start or index > end:
            return
        self.tree[node] += dif
        if start == end:
            return
        mid = (start + end) // 2
        self.update_(start, mid, node * 2, index, dif)
        self.update_(mid + 1, end, node * 2 + 1, index, dif)

    def update(self, i: int, val: int) -> None:
        dif = val - self.nums[i]
        self.nums[i] = val
        self.update_(0, len(self.nums) - 1, 1, i, dif)

    def sum_(self, start: int, end: int, node: int, left: int, right: int) -> int:
        if end < left or right < start:
            return 0
        if left <= start and end <= right:
            return self.tree[node]
        mid = (start + end) // 2
        return self.sum_(start, mid, node * 2, left, right) + self.sum_(mid + 1, end, node * 2 + 1, left, right)

    def sumRange(self, i: int, j: int) -> int:
        return self.sum_(0, len(self.nums) - 1, 1, i, j)
        

# Your NumArray object will be instantiated and called as such:
nums = [1, 3, 5]
obj = NumArray(nums)
obj.update(1, 2)
print(obj.sumRange(0, 2))

 

Approach 3 : without initialize function, and use update_ function to init(reference from https://ggodong.tistory.com/221)

 

 

from typing import List

class NumArray:

    def __init__(self, nums: List[int]):
        self.nums = nums
        self.tree = [0] * (4 * len(nums))
        #self.tree_init(0, len(nums) - 1, 1)
        #print(self.tree)
        for key, value in enumerate(nums):
            self.update_(0, len(nums) - 1, 1, key, value)

        
    # def tree_init(self, start: int, end: int, node: int) -> int:
    #     if start == end:
    #         #print(node, start, end)
    #         self.tree[node] = self.nums[start]
    #         return self.tree[node]
    #     mid = (start + end) // 2
    #     self.tree[node] = self.tree_init(start, mid, node * 2) + self.tree_init(mid + 1, end, node * 2 + 1)
    #     return self.tree[node]
    
    def update_(self, start: int, end: int, node: int, index: int, dif: int) -> None:
        if index < start or index > end:
            return
        self.tree[node] += dif
        if start == end:
            return
        mid = (start + end) // 2
        self.update_(start, mid, node * 2, index, dif)
        self.update_(mid + 1, end, node * 2 + 1, index, dif)

    def update(self, i: int, val: int) -> None:
        dif = val - self.nums[i]
        self.nums[i] = val
        self.update_(0, len(self.nums) - 1, 1, i, dif)
        # print("update: ", i, val, self.nums, self.tree)

    def sum_(self, start: int, end: int, node: int, left: int, right: int) -> int:
        if end < left or right < start:
            return 0
        if left <= start and end <= right:
            return self.tree[node]
        mid = (start + end) // 2
        return self.sum_(start, mid, node * 2, left, right) + self.sum_(mid + 1, end, node * 2 + 1, left, right)

    def sumRange(self, i: int, j: int) -> int:
        return self.sum_(0, len(self.nums) - 1, 1, i, j)