Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 436e996

Browse files
committed
Rewrite Range Sum Query Mutable with BIT and Segment Tree
1 parent 9648d0d commit 436e996

File tree

4 files changed

+206
-119
lines changed

4 files changed

+206
-119
lines changed
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
JAVA := java
2-
JAVAC := javac
3-
JAVACFLAGS := -Xlint:all
1+
CXX := g++
2+
CXXFLAGS := -std=c++11 -Wall -o out
43

5-
default: clean build run
4+
default: build run
65

76
build:
8-
$(JAVAC) $(JAVACFLAGS) NumArray.java
7+
$(CXX) $(CXXFLAGS) main.cpp
98

109
clean:
11-
$(RM) NumArray.class
10+
$(RM) out
1211

1312
run:
14-
$(JAVA) NumArray
13+
./out

leetcode/algorithms/range-sum-query-mutable/NumArray.java

Lines changed: 0 additions & 111 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
#README
1+
# README
22

33
[https://leetcode.com/problems/range-sum-query-mutable/](https://leetcode.com/problems/range-sum-query-mutable/)
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#include <cassert>
2+
#include <iostream>
3+
#include <vector>
4+
5+
#define USE_BIT true
6+
7+
#if USE_BIT
8+
9+
//
10+
// Binary Index/Fenwick Tree implementation. See TopCoder article for tutorial.
11+
//
12+
// https://www.topcoder.com/community/data-science/data-science-tutorials/binary-indexed-trees/
13+
//
14+
class NumArray {
15+
private:
16+
// The underlying BIT.
17+
std::vector<int> T;
18+
19+
//
20+
// Returns the sum of the first i elements of N in O(log |N|) time.
21+
//
22+
int query(int i) {
23+
int s = 0;
24+
25+
while (i > 0) {
26+
s += T[i];
27+
i -= (i & -i);
28+
}
29+
30+
return s;
31+
}
32+
33+
public:
34+
explicit NumArray(std::vector<int> N): T(N.size() + 1, 0) {
35+
for (size_t i = 0; i < N.size(); i++) {
36+
update(i, N[i]);
37+
}
38+
}
39+
40+
//
41+
// Updates the value at index i in the array by x in O(log |N|) time.
42+
//
43+
void update(int i, int x) {
44+
int n = static_cast<int>(T.size());
45+
46+
assert(i >= 0 && i < n - 1);
47+
48+
int d = x - sumRange(i, i); // Calculate the change in N[i].
49+
i++;
50+
51+
while (i < n) {
52+
T[i] += d;
53+
i += (i & -i);
54+
}
55+
}
56+
57+
//
58+
// Returns sum of N[i...j] in O(log |N|) time.
59+
//
60+
int sumRange(int i, int j) {
61+
int n = static_cast<int>(T.size());
62+
63+
assert(i >= 0 && i < n - 1);
64+
assert(j >= 0 && j < n - 1);
65+
assert(i <= j);
66+
67+
return query(j + 1) - query(i);
68+
}
69+
};
70+
71+
#else
72+
73+
//
74+
// Segment Tree implementation. See Top Coder article for tutorial.
75+
//
76+
// https://www.topcoder.com/community/data-science/data-science-tutorials/range-minimum-query-and-lowest-common-ancestor/#Segment_Trees
77+
//
78+
class NumArray {
79+
private:
80+
// The underlying segment tree with T[i] = Sum of elements i node i's range.
81+
std::vector<int> T;
82+
83+
// Size of the original array.
84+
int n;
85+
86+
//
87+
// Builds the Segment Tree at node k with sum of range N[lo...hi] and returns
88+
// the number nodes used in T.
89+
//
90+
int build(int k, int lo, int hi, const std::vector<int>& N) {
91+
if (lo == hi) {
92+
T[k] = N[lo];
93+
return k + 1;
94+
} else {
95+
int mid = lo + (hi - lo) / 2;
96+
int nodes = std::max(build(k * 2 + 1, lo, mid, N),
97+
build(k * 2 + 2, mid + 1, hi, N));
98+
T[k] = T[k * 2 + 1] + T[k * 2 + 2];
99+
return nodes;
100+
}
101+
}
102+
103+
//
104+
// Returns the sum of the portion of range N[i...j] in node k with range
105+
// N[lo...hi].
106+
//
107+
int query(int k, int lo, int hi, int i, int j) {
108+
if (lo >= i && hi <= j) {
109+
return T[k]; // This node partially represents the query range.
110+
} else if (lo > j || hi < i) {
111+
return 0; // This node does not contain the query range.
112+
}
113+
114+
int mid = lo + (hi - lo) / 2;
115+
return query(k * 2 + 1, lo, mid, i, j) +
116+
query(k * 2 + 2, mid + 1, hi, i, j);
117+
}
118+
119+
//
120+
// Updates index i with value x in node k with range N[lo..hi].
121+
//
122+
void update(int k, int lo, int hi, int i, int x) {
123+
if (i < lo || i > hi) {
124+
return; // Index i is not in range of node k!
125+
} else if (lo == hi) {
126+
T[k] = x;
127+
} else {
128+
int mid = lo + (hi - lo) / 2;
129+
update(k * 2 + 1, lo, mid, i, x);
130+
update(k * 2 + 2, mid + 1, hi, i, x);
131+
T[k] = T[k * 2 + 1] + T[k * 2 + 2];
132+
}
133+
}
134+
135+
public:
136+
explicit NumArray(std::vector<int> N): n(N.size()) {
137+
if (N.empty()) return;
138+
139+
// Calculate the smallest number of leaves in a full binary tree with at
140+
// least |N| leaves.
141+
int p = 1;
142+
while (p < static_cast<int>(N.size())) p *= 2;
143+
144+
// Build the Segment Tree in O(|N|) time.
145+
T.resize(p * 2 - 1);
146+
int nodes = build(0, 0, N.size() - 1, N);
147+
T.resize(nodes);
148+
}
149+
150+
//
151+
// Updates the value at index i in the array to x in O(log |N|) time.
152+
//
153+
void update(int i, int x) {
154+
assert(i >= 0 && i < n);
155+
update(0, 0, n - 1, i, x);
156+
}
157+
158+
//
159+
// Returns sum of [i, j] in O(log |N|) time.
160+
//
161+
int sumRange(int i, int j) {
162+
assert(i >= 0 && i < n);
163+
assert(j >= 0 && j < n);
164+
assert(i <= j);
165+
166+
return query(0, 0, n - 1, i, j);
167+
}
168+
};
169+
170+
#endif
171+
172+
//
173+
// Delete before submitting to LeetCode.
174+
//
175+
int main() {
176+
std::cout << "Begin tests..." << std::endl;
177+
178+
NumArray _({});
179+
180+
NumArray array({1, 2, 3, 4, 5});
181+
assert(array.sumRange(0, 1) == 3);
182+
assert(array.sumRange(2, 2) == 3);
183+
assert(array.sumRange(0, 4) == 15);
184+
185+
array.update(2, 0);
186+
assert(array.sumRange(0, 1) == 3);
187+
assert(array.sumRange(2, 2) == 0);
188+
assert(array.sumRange(0, 4) == 12);
189+
190+
array.update(2, 1);
191+
assert(array.sumRange(0, 1) == 3);
192+
assert(array.sumRange(2, 2) == 1);
193+
assert(array.sumRange(0, 4) == 13);
194+
195+
std::cout << "Tests pass!" << std::endl;
196+
std::cout << "Please run this solution on LeetCode." << std::endl;
197+
std::cout << "https://leetcode.com/articles/range-sum-query-mutable/" << std::endl; // NOLINT
198+
return 0;
199+
}

0 commit comments

Comments
 (0)