Skip to content

Commit ab4b3e9

Browse files
committed
feat: add solutions to lc problem: No.0308
No.0308.Range Sum Query 2D - Mutable
1 parent edde105 commit ab4b3e9

File tree

6 files changed

+777
-0
lines changed

6 files changed

+777
-0
lines changed

solution/0300-0399/0308.Range Sum Query 2D - Mutable/README.md

+269
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,291 @@ numMatrix.sumRegion(2, 1, 4, 3); // 返回 10 (即,右侧红色矩形的和)
6161

6262
<!-- 这里可写通用的实现逻辑 -->
6363

64+
树状数组。
65+
66+
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
67+
68+
1. **单点更新** `update(x, delta)`: 把序列 x 位置的数加上一个值 delta;
69+
1. **前缀和查询** `query(x)`:查询序列 `[1,...x]` 区间的区间和,即位置 x 的前缀和。
70+
71+
这两个操作的时间复杂度均为 `O(log n)`
72+
73+
对于本题,可以构建二维树状数组。
74+
6475
<!-- tabs:start -->
6576

6677
### **Python3**
6778

6879
<!-- 这里可写当前语言的特殊实现逻辑 -->
6980

7081
```python
82+
class BinaryIndexedTree:
83+
def __init__(self, n):
84+
self.n = n
85+
self.c = [0] * (n + 1)
86+
87+
@staticmethod
88+
def lowbit(x):
89+
return x & -x
90+
91+
def update(self, x, delta):
92+
while x <= self.n:
93+
self.c[x] += delta
94+
x += BinaryIndexedTree.lowbit(x)
95+
96+
def query(self, x):
97+
s = 0
98+
while x > 0:
99+
s += self.c[x]
100+
x -= BinaryIndexedTree.lowbit(x)
101+
return s
102+
103+
104+
class NumMatrix:
105+
106+
def __init__(self, matrix: List[List[int]]):
107+
self.trees = []
108+
n = len(matrix[0])
109+
for row in matrix:
110+
tree = BinaryIndexedTree(n)
111+
for j, v in enumerate(row):
112+
tree.update(j + 1, v)
113+
self.trees.append(tree)
71114

115+
def update(self, row: int, col: int, val: int) -> None:
116+
tree = self.trees[row]
117+
prev = tree.query(col + 1) - tree.query(col)
118+
tree.update(col + 1, val - prev)
119+
120+
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
121+
return sum(tree.query(col2 + 1) - tree.query(col1) for tree in self.trees[row1: row2 + 1])
122+
123+
124+
# Your NumMatrix object will be instantiated and called as such:
125+
# obj = NumMatrix(matrix)
126+
# obj.update(row,col,val)
127+
# param_2 = obj.sumRegion(row1,col1,row2,col2)
72128
```
73129

74130
### **Java**
75131

76132
<!-- 这里可写当前语言的特殊实现逻辑 -->
77133

78134
```java
135+
class BinaryIndexedTree {
136+
private int n;
137+
private int[] c;
138+
139+
public BinaryIndexedTree(int n) {
140+
this.n = n;
141+
c = new int[n + 1];
142+
}
143+
144+
public void update(int x, int delta) {
145+
while (x <= n) {
146+
c[x] += delta;
147+
x += lowbit(x);
148+
}
149+
}
150+
151+
public int query(int x) {
152+
int s = 0;
153+
while (x > 0) {
154+
s += c[x];
155+
x -= lowbit(x);
156+
}
157+
return s;
158+
}
159+
160+
public static int lowbit(int x) {
161+
return x & -x;
162+
}
163+
}
164+
165+
class NumMatrix {
166+
private BinaryIndexedTree[] trees;
167+
168+
public NumMatrix(int[][] matrix) {
169+
int m = matrix.length;
170+
int n = matrix[0].length;
171+
trees = new BinaryIndexedTree[m];
172+
for (int i = 0; i < m; ++i) {
173+
BinaryIndexedTree tree = new BinaryIndexedTree(n);
174+
for (int j = 0; j < n; ++j) {
175+
tree.update(j + 1, matrix[i][j]);
176+
}
177+
trees[i] = tree;
178+
}
179+
}
180+
181+
public void update(int row, int col, int val) {
182+
BinaryIndexedTree tree = trees[row];
183+
int prev = tree.query(col + 1) - tree.query(col);
184+
tree.update(col + 1, val - prev);
185+
}
186+
187+
public int sumRegion(int row1, int col1, int row2, int col2) {
188+
int s = 0;
189+
for (int i = row1; i <= row2; ++i) {
190+
BinaryIndexedTree tree = trees[i];
191+
s += tree.query(col2 + 1) - tree.query(col1);
192+
}
193+
return s;
194+
}
195+
}
196+
197+
/**
198+
* Your NumMatrix object will be instantiated and called as such:
199+
* NumMatrix obj = new NumMatrix(matrix);
200+
* obj.update(row,col,val);
201+
* int param_2 = obj.sumRegion(row1,col1,row2,col2);
202+
*/
203+
```
204+
205+
### **C++**
206+
207+
```cpp
208+
class BinaryIndexedTree {
209+
public:
210+
int n;
211+
vector<int> c;
212+
213+
BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
214+
215+
void update(int x, int delta) {
216+
while (x <= n)
217+
{
218+
c[x] += delta;
219+
x += lowbit(x);
220+
}
221+
}
222+
223+
int query(int x) {
224+
int s = 0;
225+
while (x > 0)
226+
{
227+
s += c[x];
228+
x -= lowbit(x);
229+
}
230+
return s;
231+
}
232+
233+
int lowbit(int x) {
234+
return x & -x;
235+
}
236+
};
237+
238+
class NumMatrix {
239+
public:
240+
vector<BinaryIndexedTree*> trees;
241+
242+
NumMatrix(vector<vector<int>>& matrix) {
243+
int m = matrix.size();
244+
int n = matrix[0].size();
245+
trees.resize(m);
246+
for (int i = 0; i < m; ++i) {
247+
BinaryIndexedTree* tree = new BinaryIndexedTree(n);
248+
for (int j = 0; j < n; ++j) tree->update(j + 1, matrix[i][j]);
249+
trees[i] = tree;
250+
}
251+
}
252+
253+
void update(int row, int col, int val) {
254+
BinaryIndexedTree* tree = trees[row];
255+
int prev = tree->query(col + 1) - tree->query(col);
256+
tree->update(col + 1, val - prev);
257+
}
258+
259+
int sumRegion(int row1, int col1, int row2, int col2) {
260+
int s = 0;
261+
for (int i = row1; i <= row2; ++i)
262+
{
263+
BinaryIndexedTree* tree = trees[i];
264+
s += tree->query(col2 + 1) - tree->query(col1);
265+
}
266+
return s;
267+
}
268+
};
269+
270+
/**
271+
* Your NumMatrix object will be instantiated and called as such:
272+
* NumMatrix* obj = new NumMatrix(matrix);
273+
* obj->update(row,col,val);
274+
* int param_2 = obj->sumRegion(row1,col1,row2,col2);
275+
*/
276+
```
277+
278+
### **Go**
279+
280+
```go
281+
type BinaryIndexedTree struct {
282+
n int
283+
c []int
284+
}
285+
286+
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
287+
c := make([]int, n+1)
288+
return &BinaryIndexedTree{n, c}
289+
}
290+
291+
func (this *BinaryIndexedTree) lowbit(x int) int {
292+
return x & -x
293+
}
294+
295+
func (this *BinaryIndexedTree) update(x, delta int) {
296+
for x <= this.n {
297+
this.c[x] += delta
298+
x += this.lowbit(x)
299+
}
300+
}
301+
302+
func (this *BinaryIndexedTree) query(x int) int {
303+
s := 0
304+
for x > 0 {
305+
s += this.c[x]
306+
x -= this.lowbit(x)
307+
}
308+
return s
309+
}
310+
311+
type NumMatrix struct {
312+
trees []*BinaryIndexedTree
313+
}
314+
315+
func Constructor(matrix [][]int) NumMatrix {
316+
n := len(matrix[0])
317+
var trees []*BinaryIndexedTree
318+
for _, row := range matrix {
319+
tree := newBinaryIndexedTree(n)
320+
for j, v := range row {
321+
tree.update(j+1, v)
322+
}
323+
trees = append(trees, tree)
324+
}
325+
return NumMatrix{trees}
326+
}
327+
328+
func (this *NumMatrix) Update(row int, col int, val int) {
329+
tree := this.trees[row]
330+
prev := tree.query(col+1) - tree.query(col)
331+
tree.update(col+1, val-prev)
332+
}
333+
334+
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
335+
s := 0
336+
for i := row1; i <= row2; i++ {
337+
tree := this.trees[i]
338+
s += tree.query(col2+1) - tree.query(col1)
339+
}
340+
return s
341+
}
79342
343+
/**
344+
* Your NumMatrix object will be instantiated and called as such:
345+
* obj := Constructor(matrix);
346+
* obj.Update(row,col,val);
347+
* param_2 := obj.SumRegion(row1,col1,row2,col2);
348+
*/
80349
```
81350

82351
### **...**

0 commit comments

Comments
 (0)