Skip to content

Commit 6b16776

Browse files
committed
feat: add solutions to lc poroblem: No.0307
No.0307.Range Sum Query - Mutable
1 parent 583fe30 commit 6b16776

File tree

2 files changed

+481
-1
lines changed

2 files changed

+481
-1
lines changed

solution/0300-0399/0307.Range Sum Query - Mutable/README.md

+242
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
5656

5757
<!-- 这里可写通用的实现逻辑 -->
5858

59+
**方法一:树状数组**
60+
5961
树状数组。
6062

6163
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
@@ -65,6 +67,8 @@ numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
6567

6668
这两个操作的时间复杂度均为 `O(log n)`
6769

70+
**方法二:线段树**
71+
6872
<!-- tabs:start -->
6973

7074
### **Python3**
@@ -108,6 +112,73 @@ class NumArray:
108112
return self.tree.query(right + 1) - self.tree.query(left)
109113

110114

115+
# Your NumArray object will be instantiated and called as such:
116+
# obj = NumArray(nums)
117+
# obj.update(index,val)
118+
# param_2 = obj.sumRange(left,right)
119+
```
120+
121+
```python
122+
class Node:
123+
def __init__(self):
124+
self.l = 0
125+
self.r = 0
126+
self.v = 0
127+
128+
class SegmentTree:
129+
def __init__(self, nums):
130+
n = len(nums)
131+
self.tr = [Node() for _ in range(4 * n)]
132+
self.build(1, 1, n)
133+
for i, v in enumerate(nums, 1):
134+
self.modify(1, i, v)
135+
136+
def build(self, u, l, r):
137+
self.tr[u].l = l
138+
self.tr[u].r = r
139+
if l == r:
140+
return
141+
mid = (l + r) >> 1
142+
self.build(u << 1, l, mid)
143+
self.build(u << 1 | 1, mid + 1, r)
144+
145+
def modify(self, u, x, v):
146+
if self.tr[u].l == x and self.tr[u].r == x:
147+
self.tr[u].v = v
148+
return
149+
mid = (self.tr[u].l + self.tr[u].r) >> 1
150+
if x <= mid:
151+
self.modify(u << 1, x, v)
152+
else:
153+
self.modify(u << 1 | 1, x, v)
154+
self.pushup(u)
155+
156+
def pushup(self, u):
157+
self.tr[u].v = self.tr[u << 1].v + self.tr[u << 1 | 1].v
158+
159+
def query(self, u, l, r):
160+
if self.tr[u].l >= l and self.tr[u].r <= r:
161+
return self.tr[u].v
162+
mid = (self.tr[u].l + self.tr[u].r) >> 1
163+
v = 0
164+
if l <= mid:
165+
v = self.query(u << 1, l, r)
166+
if r > mid:
167+
v += self.query(u << 1 | 1, l, r)
168+
return v
169+
170+
class NumArray:
171+
172+
def __init__(self, nums: List[int]):
173+
self.tree = SegmentTree(nums)
174+
175+
def update(self, index: int, val: int) -> None:
176+
self.tree.modify(1, index + 1, val)
177+
178+
def sumRange(self, left: int, right: int) -> int:
179+
return self.tree.query(1, left + 1, right + 1)
180+
181+
111182
# Your NumArray object will be instantiated and called as such:
112183
# obj = NumArray(nums)
113184
# obj.update(index,val)
@@ -178,6 +249,97 @@ class NumArray {
178249
*/
179250
```
180251

252+
```java
253+
class Node {
254+
int l;
255+
int r;
256+
int v;
257+
}
258+
259+
class SegmentTree {
260+
private Node[] tr;
261+
262+
public SegmentTree(int[] nums) {
263+
int n = nums.length;
264+
tr = new Node[4 * n];
265+
for (int i = 0; i < tr.length; ++i) {
266+
tr[i] = new Node();
267+
}
268+
build(1, 1, n);
269+
for (int i = 0; i < n; ++i) {
270+
modify(1, i + 1, nums[i]);
271+
}
272+
}
273+
274+
public void build(int u, int l, int r) {
275+
tr[u].l = l;
276+
tr[u].r = r;
277+
if (l == r) {
278+
return;
279+
}
280+
int mid = (l + r) >> 1;
281+
build(u << 1, l, mid);
282+
build(u << 1 | 1, mid + 1, r);
283+
}
284+
285+
public void modify(int u, int x, int v) {
286+
if (tr[u].l == x && tr[u].r == x) {
287+
tr[u].v = v;
288+
return;
289+
}
290+
int mid = (tr[u].l + tr[u].r) >> 1;
291+
if (x <= mid) {
292+
modify(u << 1, x, v);
293+
} else {
294+
modify(u << 1 | 1, x, v);
295+
}
296+
pushup(u);
297+
}
298+
299+
public void pushup(int u) {
300+
tr[u].v = tr[u << 1].v + tr[u << 1 | 1].v;
301+
}
302+
303+
public int query(int u, int l, int r) {
304+
if (tr[u].l >= l && tr[u].r <= r) {
305+
return tr[u].v;
306+
}
307+
int mid = (tr[u].l + tr[u].r) >> 1;
308+
int v = 0;
309+
if (l <= mid) {
310+
v = query(u << 1, l, r);
311+
}
312+
if (r > mid) {
313+
v += query(u << 1 | 1, l, r);
314+
}
315+
return v;
316+
}
317+
}
318+
319+
class NumArray {
320+
private SegmentTree tree;
321+
322+
public NumArray(int[] nums) {
323+
tree = new SegmentTree(nums);
324+
}
325+
326+
public void update(int index, int val) {
327+
tree.modify(1, index + 1, val);
328+
}
329+
330+
public int sumRange(int left, int right) {
331+
return tree.query(1, left + 1, right + 1);
332+
}
333+
}
334+
335+
/**
336+
* Your NumArray object will be instantiated and called as such:
337+
* NumArray obj = new NumArray(nums);
338+
* obj.update(index,val);
339+
* int param_2 = obj.sumRange(left,right);
340+
*/
341+
```
342+
181343
### **C++**
182344

183345
```cpp
@@ -240,6 +402,86 @@ public:
240402
*/
241403
```
242404
405+
```cpp
406+
class Node {
407+
public:
408+
int l;
409+
int r;
410+
int v;
411+
};
412+
413+
class SegmentTree {
414+
public:
415+
vector<Node*> tr;
416+
417+
SegmentTree(vector<int>& nums) {
418+
int n = nums.size();
419+
tr.resize(4 * n);
420+
for (int i = 0; i < tr.size(); ++i) tr[i] = new Node();
421+
build(1, 1, n);
422+
for (int i = 0; i < n; ++i) modify(1, i + 1, nums[i]);
423+
}
424+
425+
void build(int u, int l, int r) {
426+
tr[u]->l = l;
427+
tr[u]->r = r;
428+
if (l == r) return;
429+
int mid = (l + r) >> 1;
430+
build(u << 1, l, mid);
431+
build(u << 1 | 1, mid + 1, r);
432+
}
433+
434+
void modify(int u, int x, int v) {
435+
if (tr[u]->l == x && tr[u]->r == x)
436+
{
437+
tr[u]->v = v;
438+
return;
439+
}
440+
int mid = (tr[u]->l + tr[u]->r) >> 1;
441+
if (x <= mid) modify(u << 1, x, v);
442+
else modify(u << 1 | 1, x, v);
443+
pushup(u);
444+
}
445+
446+
void pushup(int u) {
447+
tr[u]->v = tr[u << 1]->v + tr[u << 1 | 1]->v;
448+
}
449+
450+
int query(int u, int l, int r) {
451+
if (tr[u]->l >= l && tr[u]->r <= r) return tr[u]->v;
452+
int mid = (tr[u]->l + tr[u]->r) >> 1;
453+
int v = 0;
454+
if (l <= mid) v = query(u << 1, l, r);
455+
if (r > mid) v += query(u << 1 | 1, l, r);
456+
return v;
457+
}
458+
};
459+
460+
class NumArray {
461+
public:
462+
SegmentTree* tree;
463+
464+
NumArray(vector<int>& nums) {
465+
tree = new SegmentTree(nums);
466+
}
467+
468+
void update(int index, int val) {
469+
return tree->modify(1, index + 1, val);
470+
}
471+
472+
int sumRange(int left, int right) {
473+
return tree->query(1, left + 1, right + 1);
474+
}
475+
};
476+
477+
/**
478+
* Your NumArray object will be instantiated and called as such:
479+
* NumArray* obj = new NumArray(nums);
480+
* obj->update(index,val);
481+
* int param_2 = obj->sumRange(left,right);
482+
*/
483+
```
484+
243485
### **Go**
244486

245487
```go

0 commit comments

Comments
 (0)