@@ -61,22 +61,291 @@ numMatrix.sumRegion(2, 1, 4, 3); // 返回 10 (即,右侧红色矩形的和)
61
61
62
62
<!-- 这里可写通用的实现逻辑 -->
63
63
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
+
64
75
<!-- tabs:start -->
65
76
66
77
### ** Python3**
67
78
68
79
<!-- 这里可写当前语言的特殊实现逻辑 -->
69
80
70
81
``` 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)
71
114
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)
72
128
```
73
129
74
130
### ** Java**
75
131
76
132
<!-- 这里可写当前语言的特殊实现逻辑 -->
77
133
78
134
``` 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
+ }
79
342
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
+ */
80
349
```
81
350
82
351
### ** ...**
0 commit comments