-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy path206.interval-sum.py
113 lines (96 loc) · 3.13 KB
/
206.interval-sum.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Tag: Segment Tree
# Time: O(N)
# Space: O(N)
# Ref: -
# Note: -
# Given an integer array (index from 0 to n-1, where n is the size of this array), and an query list.
# Each query has two integers `[start, end]`.
# For each query, calculate the sum of numbers between index start and end in the given array and return in the result list.
#
# **Example 1:**
# ```
# Input: array = [1,2,7,8,5], queries = [(0,4),(1,2),(2,4)]
# Output: [23,9,20]
# ```
#
# **Example 2:**
# ```
# Input: array = [4,3,1,2], queries = [(1,2),(0,2)]
# Output: [4,8]
# ```
#
# We suggest you finish problem [Segment Tree Build](https://www.lintcode.com/problem/segment-tree-build/ ), [Segment Tree Query](https://www.lintcode.com/problem/segment-tree-query/) and [Segment Tree Modify](https://www.lintcode.com/problem/segment-tree-modify/) first.
from typing import (
List,
)
from lintcode import (
Interval,
)
"""
Definition of Interval:
class Interval(object):
def __init__(self, start, end):
self.start = start
self.end = end
"""
class Solution:
"""
@param a: An integer list
@param queries: An query list
@return: The result list
"""
def interval_sum(self, a: List[int], queries: List[Interval]) -> List[int]:
# write your code here
prefix_sum = [0]
for x in a:
prefix_sum.append(prefix_sum[-1] + x)
res = []
for interval in queries:
res.append(prefix_sum[interval.end + 1] - prefix_sum[interval.start])
return res
# Follow up
class SegmentTreeNode:
def __init__(self, start, end):
self.start, self.end = start, end
self.left, self.right = None, None
self.sum = 0
class Solution:
"""
@param a: An integer list
@param queries: An query list
@return: The result list
"""
def interval_sum(self, a: List[int], queries: List[Interval]) -> List[int]:
# write your code here
root = self.build(0, len(a) - 1, a)
res = []
for q in queries:
sum = self.query(root, q.start, q.end)
res.append(sum)
return res
def query(self, root: SegmentTreeNode, start: int, end: int) -> int:
if root is None:
return 0
if root.start == start and root.end == end:
return root.sum
mid = root.start + (root.end - root.start) // 2
if end <= mid:
return self.query(root.left, start, end)
elif start > mid:
return self.query(root.right, start, end)
else:
left = self.query(root.left, start, mid)
right = self.query(root.right, mid + 1, end)
return left + right
def build(self, start: int, end: int, vals: list) -> SegmentTreeNode:
if start > end:
return None
node = SegmentTreeNode(start, end)
if start == end:
node.sum = vals[start]
return node
mid = start + (end - start) // 2
node.left = self.build(start, mid, vals)
node.right = self.build(mid + 1, end, vals)
node.sum = node.left.sum + node.right.sum
return node