Skip to content

Commit 0e10183

Browse files
committed
Solve #307
1 parent f8f1aa7 commit 0e10183

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,4 @@ mod n0303_range_sum_query_immutable;
229229
mod n0304_range_sum_query_2d_immutable;
230230
mod n1009_pancake_sorting;
231231
mod n0306_additive_number;
232+
mod n0307_range_sum_query_mutable;

src/n0307_range_sum_query_mutable.rs

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/**
2+
* [307] Range Sum Query - Mutable
3+
*
4+
* Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.
5+
*
6+
* The update(i, val) function modifies nums by updating the element at index i to val.
7+
*
8+
* Example:
9+
*
10+
*
11+
* Given nums = [1, 3, 5]
12+
*
13+
* sumRange(0, 2) -> 9
14+
* update(1, 2)
15+
* sumRange(0, 2) -> 8
16+
*
17+
*
18+
* Note:
19+
*
20+
* <ol>
21+
* The array is only modifiable by the update function.
22+
* You may assume the number of calls to update and sumRange function is distributed evenly.
23+
* </ol>
24+
*
25+
*/
26+
pub struct Solution {}
27+
28+
// Segement Tree
29+
//
30+
// N[0:6]
31+
// / \
32+
// / \
33+
// N[0:3] N[4:6]
34+
// / \ / \
35+
// N[0:1] N[2:3] N[4:5] N[6]
36+
// / \ / \ / \
37+
// N[0] N[1] N[2] N[3] N[4] N[5]
38+
//
39+
// submission codes start here
40+
41+
struct NumArray {
42+
tree: Vec<i32>,
43+
n: usize,
44+
}
45+
46+
/**
47+
* `&self` means the method takes an immutable reference.
48+
* If you need a mutable reference, change it to `&mut self` instead.
49+
*/
50+
impl NumArray {
51+
fn new(nums: Vec<i32>) -> Self {
52+
let n = nums.len();
53+
let mut tree = vec![0; 4*n];
54+
if n > 0 {
55+
NumArray::build(1, 0, n-1, &mut tree, &nums);
56+
}
57+
NumArray{tree: tree, n: n}
58+
}
59+
60+
fn update(&mut self, i: i32, val: i32) {
61+
NumArray::update_internal(i as usize, val, 1, 0, self.n-1, &mut self.tree);
62+
}
63+
64+
fn sum_range(&self, i: i32, j: i32) -> i32 {
65+
NumArray::sum(1, 0, self.n-1, i as usize, j as usize, &self.tree)
66+
}
67+
68+
fn build(node: usize, start: usize, end: usize, tree: &mut Vec<i32>, nums: &Vec<i32>) {
69+
if start == end {
70+
tree[node] = nums[start];
71+
} else {
72+
let mid = (start + end) / 2;
73+
NumArray::build(2*node, start, mid, tree, nums);
74+
NumArray::build(2*node+1, mid+1, end, tree, nums);
75+
tree[node] = tree[2*node] + tree[2*node+1];
76+
}
77+
}
78+
79+
fn update_internal(i: usize, val: i32, node: usize, start: usize, end: usize, tree: &mut Vec<i32>) {
80+
if start == end {
81+
tree[node] = val;
82+
} else {
83+
let mid = (start + end) / 2;
84+
if i <= mid {
85+
NumArray::update_internal(i, val, 2*node, start, mid, tree);
86+
} else {
87+
NumArray::update_internal(i, val, 2*node+1, mid+1, end, tree);
88+
}
89+
tree[node] = tree[2*node] + tree[2*node+1];
90+
}
91+
}
92+
93+
fn sum(node: usize, start: usize, end: usize, left: usize, right: usize, tree: &Vec<i32>) -> i32 {
94+
if right < start || left > end {
95+
// not in range
96+
0
97+
} else if left <= start && end <= right {
98+
// completely in range
99+
tree[node]
100+
} else {
101+
// partially in range
102+
let mid = (start + end) / 2;
103+
NumArray::sum(2*node, start, mid, left, right, tree) +
104+
NumArray::sum(2*node+1, mid+1, end, left, right ,tree)
105+
}
106+
}
107+
}
108+
109+
/**
110+
* Your NumArray object will be instantiated and called as such:
111+
* let obj = NumArray::new(nums);
112+
* obj.update(i, val);
113+
* let ret_2: i32 = obj.sum_range(i, j);
114+
*/
115+
116+
// submission codes end
117+
118+
#[cfg(test)]
119+
mod tests {
120+
use super::*;
121+
122+
#[test]
123+
fn test_307() {
124+
let _empty = NumArray::new(vec![]);
125+
let mut tree = NumArray::new(vec![1,1,1,1,1,1,1,1,1,1]);
126+
assert_eq!(tree.sum_range(0, 6), 7);
127+
tree.update(0, 2);
128+
assert_eq!(tree.sum_range(0, 6), 8);
129+
tree.update(1, 2);
130+
assert_eq!(tree.sum_range(0, 2), 5);
131+
tree.update(6, 10);
132+
assert_eq!(tree.sum_range(6, 6), 10);
133+
}
134+
}

0 commit comments

Comments
 (0)