-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRangeSumQuery.py
More file actions
146 lines (127 loc) · 4.1 KB
/
RangeSumQuery.py
File metadata and controls
146 lines (127 loc) · 4.1 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# 303. Range Sum Query - Immutable
class NumArray:
# dp[i]表示0到i-1位的数之和,这里设dp[0]是为了应对i=0的情况
def __init__(self, nums):
"""
:type nums: List[int]
"""
n = len(nums)
self.dp = [0] * (n + 1)
for i in range(n):
self.dp[i+1] = self.dp[i] + nums[i]
def sumRange(self, i, j):
"""
:type i: int
:type j: int
:rtype: int
"""
return self.dp[j+1] - self.dp[i]
# 304. Range Sum Query 2D - Immutable
class NumMatrix:
# dp[i][j]表示右上角为[i-1, j-1]的点组成的矩形的总和
def __init__(self, matrix):
"""
:type matrix: List[List[int]]
"""
n = len(matrix)
m = len(matrix[0])
self.dp = [[0] * (m + 1) for i in range(n + 1)]
for i in range(n):
for j in range(m):
self.dp[i+1][j+1] = self.dp[i+1][j] + self.dp[i][j+1] - self.dp[i][j] + matrix[i][j]
def sumRegion(self, row1, col1, row2, col2):
"""
:type row1: int
:type col1: int
:type row2: int
:type col2: int
:rtype: int
"""
# (row2, col2) - (row2, col1-1) - (row1-1, col2) + (row1-1, col1-1)
return self.dp[row2+1][col2+1] - self.dp[row2+1][col1] - self.dp[row1][col2+1] + self.dp[row1][col1]
# 307. Range Sum Query - Mutable
class NumArrayMutable:
def __init__(self, nums):
"""
:type nums: List[int]
"""
self.nums = [0] * (len(nums) + 1)
self.bits = [0] * (len(nums) + 1)
for i in range(len(nums)):
self.update(i, nums[i])
def update(self, i, val):
"""
:type i: int
:type val: int
:rtype: void
"""
diff = val - self.nums[i+1]
j = i + 1
while j < len(self.nums):
self.bits[j] += diff
j += j & (-j)
self.nums[i+1] = val
def sumRange(self, i, j):
"""
:type i: int
:type j: int
:rtype: int
"""
return self.sumPrefix(j+1) - self.sumPrefix(i)
# 表示数组前i为元素的和
def sumPrefix(self, i):
res = 0
while i > 0:
res += self.bits[i]
i -= i & (-i)
return res
# 308. Range Sum Query 2D - Mutable
# Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1)
# and lower right corner (row2, col2).
# Range Sum Query 2D
# The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.
# Example:
# Given matrix = [
# [3, 0, 1, 4, 2],
# [5, 6, 3, 2, 1],
# [1, 2, 0, 1, 5],
# [4, 1, 0, 1, 7],
# [1, 0, 3, 0, 5]
# ]
#
# sumRegion(2, 1, 4, 3) -> 8
# update(3, 2, 2)
# sumRegion(2, 1, 4, 3) -> 10
# Note:
# The matrix is only modifiable by the update function.
# You may assume the number of calls to update and sumRegion function is distributed evenly.
# You may assume that row1 ≤ row2 and col1 ≤ col2.
class NumMatrix2:
# 与308思路一样,利用树状数组,把问题放到二维
def __init__(self, matrix):
m = len(matrix)
n = len(matrix[0])
self.matrix = [[0] * (n + 1) for i in range(m + 1)]
self.bits = [[0] * (n + 1) for i in range(m + 1)]
for i in range(m):
for j in range(n):
self.update(i, j, matrix[i][j])
def update(self, i, j, val):
diff = val - self.matrix[i+1][j+1]
i, j = i + 1, j + 1
self.matrix[i][j] = val
while i < len(self.matrix):
while j < len(self.matrix[0]):
self.bits[i][j] += diff
i += i & (-i)
j += j & (-j)
def sumRegion(self, row1, col1, row2, col2):
return self.getSum(row2+1, col2+1) - self.getSum(row2+1, col1) - self.getSum(row1, col2+1) + self.getSum(row1, col1)
def getSum(self, i, j):
res = 0
while i > 0:
while j > 0:
res += self.bits[i][j]
i -= i & (-i)
j -= j & (-j)
return res