-
Notifications
You must be signed in to change notification settings - Fork 89
Expand file tree
/
Copy pathInterval Sum II.py
More file actions
114 lines (92 loc) · 2.83 KB
/
Interval Sum II.py
File metadata and controls
114 lines (92 loc) · 2.83 KB
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
114
"""
Given an integer array in the construct method, implement two methods query(start, end) and modify(index, value):
For query(start, end), return the sum from index start to index end in the given array.
For modify(index, value), modify the number in the given index to value
Have you met this question in a real interview? Yes
Example
Given array A = [1,2,7,8,5].
query(0, 2), return 10.
modify(0, 4), change A[0] from 1 to 4.
query(0, 1), return 6.
modify(2, 1), change A[2] from 7 to 1.
query(2, 4), return 14.
Note
We suggest you finish problem Segment Tree Build, Segment Tree Query and Segment Tree Modify first.
Challenge
O(logN) time for query and modify.
"""
__author__ = 'Daniel'
DEFAULT = 0
f = lambda x, y: x+y
class Node(object):
def __init__(self, start, end, m):
self.start, self.end, self.m = start, end, m
self.left, self.right = None, None
class SegmentTree(object):
def __init__(self, A):
self.A = A
self.root = self.build_tree(0, len(self.A))
def build_tree(self, s, e):
"""
segment: [s, e)
"""
if s >= e:
return None
if s+1 == e:
return Node(s, e, self.A[s])
left = self.build_tree(s, (s+e)/2)
right = self.build_tree((s+e)/2, e)
val = DEFAULT
if left: val = f(val, left.m)
if right: val = f(val, right.m)
root = Node(s, e, val)
root.left = left
root.right = right
return root
def query(self, root, s, e):
"""
:type root: Node
"""
if not root:
return DEFAULT
if s <= root.start and e >= root.end:
return root.m
if s >= root.end or e <= root.start:
return DEFAULT
l = self.query(root.left, s, e)
r = self.query(root.right, s, e)
return f(l, r)
def modify(self, root, idx, val):
"""
:type root: Node
"""
if not root or idx >= root.end or idx < root.start:
return
if idx == root.start and idx == root.end-1:
root.m = val
self.A[idx] = val
return
self.modify(root.left, idx, val)
self.modify(root.right, idx, val)
val = DEFAULT
if root.left: val = f(val, root.left.m)
if root.right: val = f(val, root.right.m)
root.m = val
class Solution:
def __init__(self, A):
"""
:param A: An integer list
:return: None
"""
self.tree = SegmentTree(A)
def query(self, start, end):
"""
:param start, end: Indices
:return: The sum from start to end
"""
return self.tree.query(self.tree.root, start, end+1)
def modify(self, index, value):
"""
modify A[index] to value.
"""
self.tree.modify(self.tree.root, index, value)