Skip to content

Commit 006c6f8

Browse files
committed
feat: add solutions to lc problem: No.0327
No.0327.Count of Range Sum/
1 parent c1f3735 commit 006c6f8

File tree

38 files changed

+2210
-153
lines changed

38 files changed

+2210
-153
lines changed

solution/0300-0399/0327.Count of Range Sum/README.md

+205-52
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,16 @@
4444

4545
<!-- 这里可写通用的实现逻辑 -->
4646

47-
离散化。
47+
树状数组。
48+
49+
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
50+
51+
1. **单点更新** `update(x, delta)`: 把序列 x 位置的数加上一个值 delta;
52+
1. **前缀和查询** `query(x)`:查询序列 `[1,...x]` 区间的区间和,即位置 x 的前缀和。
53+
54+
这两个操作的时间复杂度均为 `O(log n)`
55+
56+
本题中,对于每个下标 j,以 j 为右端点的下标对的数量,就等于 `preSum[1..j]` 中的所有整数,出现在区间 `[preSum[j] - upper, preSum[j] - lower]` 的次数。我们可以用树状数组,从左到右扫描前缀和数组,每遇到一个前缀和 s,就在树状数组中查询区间 `[preSum[j] - upper, preSum[j] - lower]` 内的整数的数量,随后将 s 更新至树状数组。
4857

4958
<!-- tabs:start -->
5059

@@ -53,27 +62,47 @@
5362
<!-- 这里可写当前语言的特殊实现逻辑 -->
5463

5564
```python
56-
class Solution:
57-
def arrayRankTransform(self, arr: List[int]) -> List[int]:
58-
def find(x):
59-
left, right = 0, len(t) - 1
60-
while left < right:
61-
mid = (left + right) >> 1
62-
if t[mid] >= x:
63-
right = mid
64-
else:
65-
left = mid + 1
66-
return left + 1
67-
68-
t = sorted(set(arr))
69-
return [find(x) for x in arr]
70-
```
65+
class BinaryIndexedTree:
66+
def __init__(self, n):
67+
self.n = n
68+
self.c = [0] * (n + 1)
69+
70+
@staticmethod
71+
def lowbit(x):
72+
return x & -x
73+
74+
def update(self, x, delta):
75+
while x <= self.n:
76+
self.c[x] += delta
77+
x += BinaryIndexedTree.lowbit(x)
78+
79+
def query(self, x):
80+
s = 0
81+
while x > 0:
82+
s += self.c[x]
83+
x -= BinaryIndexedTree.lowbit(x)
84+
return s
85+
7186

72-
```python
7387
class Solution:
74-
def arrayRankTransform(self, arr: List[int]) -> List[int]:
75-
m = {v: i for i, v in enumerate(sorted(set(arr)), 1)}
76-
return [m[v] for v in arr]
88+
def countRangeSum(self, nums: List[int], lower: int, upper: int) -> int:
89+
presum = [0]
90+
for v in nums:
91+
presum.append(presum[-1] + v)
92+
alls = set()
93+
for s in presum:
94+
alls.add(s)
95+
alls.add(s - lower)
96+
alls.add(s - upper)
97+
alls = sorted(alls)
98+
m = {v: i for i, v in enumerate(alls, 1)}
99+
tree = BinaryIndexedTree(len(m))
100+
ans = 0
101+
for s in presum:
102+
i, j = m[s - upper], m[s - lower]
103+
ans += tree.query(j) - tree.query(i - 1)
104+
tree.update(m[s], 1)
105+
return ans
77106
```
78107

79108
### **Java**
@@ -82,39 +111,123 @@ class Solution:
82111

83112
```java
84113
class Solution {
85-
public int[] arrayRankTransform(int[] arr) {
86-
Set<Integer> s = new HashSet<>();
87-
for (int v : arr) {
88-
s.add(v);
114+
public int countRangeSum(int[] nums, int lower, int upper) {
115+
int n = nums.length;
116+
long[] preSum = new long[n + 1];
117+
for (int i = 0; i < n; ++i) {
118+
preSum[i + 1] = preSum[i] + nums[i];
119+
}
120+
TreeSet<Long> ts = new TreeSet<>();
121+
for (long s : preSum) {
122+
ts.add(s);
123+
ts.add(s - upper);
124+
ts.add(s - lower);
89125
}
90-
List<Integer> alls = new ArrayList<>(s);
91-
alls.sort((a, b) -> a - b);
92-
Map<Integer, Integer> m = new HashMap<>();
93-
for (int i = 0; i < alls.size(); ++i) {
94-
m.put(alls.get(i), i + 1);
126+
Map<Long, Integer> m = new HashMap<>();
127+
int idx = 1;
128+
for (long s : ts) {
129+
m.put(s, idx++);
95130
}
96-
int[] ans = new int[arr.length];
97-
for (int i = 0; i < arr.length; ++i) {
98-
ans[i] = m.get(arr[i]);
131+
int ans = 0;
132+
BinaryIndexedTree tree = new BinaryIndexedTree(m.size());
133+
for (long s : preSum) {
134+
int i = m.get(s - upper);
135+
int j = m.get(s - lower);
136+
ans += tree.query(j) - tree.query(i - 1);
137+
tree.update(m.get(s), 1);
99138
}
100139
return ans;
101140
}
102141
}
142+
143+
class BinaryIndexedTree {
144+
private int n;
145+
private int[] c;
146+
147+
public BinaryIndexedTree(int n) {
148+
this.n = n;
149+
c = new int[n + 1];
150+
}
151+
152+
public void update(int x, int delta) {
153+
while (x <= n) {
154+
c[x] += delta;
155+
x += lowbit(x);
156+
}
157+
}
158+
159+
public int query(int x) {
160+
int s = 0;
161+
while (x > 0) {
162+
s += c[x];
163+
x -= lowbit(x);
164+
}
165+
return s;
166+
}
167+
168+
public static int lowbit(int x) {
169+
return x & -x;
170+
}
171+
}
103172
```
104173

105174
### **C++**
106175

107176
```cpp
177+
class BinaryIndexedTree {
178+
public:
179+
int n;
180+
vector<int> c;
181+
182+
BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
183+
184+
void update(int x, int delta) {
185+
while (x <= n)
186+
{
187+
c[x] += delta;
188+
x += lowbit(x);
189+
}
190+
}
191+
192+
int query(int x) {
193+
int s = 0;
194+
while (x > 0)
195+
{
196+
s += c[x];
197+
x -= lowbit(x);
198+
}
199+
return s;
200+
}
201+
202+
int lowbit(int x) {
203+
return x & -x;
204+
}
205+
};
206+
108207
class Solution {
109208
public:
110-
vector<int> arrayRankTransform(vector<int>& arr) {
111-
unordered_set<int> s(arr.begin(), arr.end());
112-
vector<int> alls(s.begin(), s.end());
113-
sort(alls.begin(), alls.end());
114-
unordered_map<int, int> m;
115-
for (int i = 0; i < alls.size(); ++i) m[alls[i]] = i + 1;
116-
vector<int> ans;
117-
for (int v : arr) ans.push_back(m[v]);
209+
int countRangeSum(vector<int>& nums, int lower, int upper) {
210+
int n = nums.size();
211+
vector<long long> preSum(n + 1);
212+
for (int i = 0; i < n; ++i) preSum[i + 1] = preSum[i] + nums[i];
213+
set<long long> alls;
214+
for (auto& s : preSum)
215+
{
216+
alls.insert(s);
217+
alls.insert(s - upper);
218+
alls.insert(s - lower);
219+
}
220+
unordered_map<long long, int> m;
221+
int idx = 1;
222+
for (auto& v : alls) m[v] = idx++;
223+
BinaryIndexedTree* tree = new BinaryIndexedTree(m.size());
224+
int ans = 0;
225+
for (auto& s : preSum)
226+
{
227+
int i = m[s - upper], j = m[s - lower];
228+
ans += tree->query(j) - tree->query(i - 1);
229+
tree->update(m[s], 1);
230+
}
118231
return ans;
119232
}
120233
};
@@ -123,23 +236,63 @@ public:
123236
### **Go**
124237
125238
```go
126-
func arrayRankTransform(arr []int) []int {
127-
s := make(map[int]bool)
128-
for _, v := range arr {
129-
s[v] = true
239+
type BinaryIndexedTree struct {
240+
n int
241+
c []int
242+
}
243+
244+
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
245+
c := make([]int, n+1)
246+
return &BinaryIndexedTree{n, c}
247+
}
248+
249+
func (this *BinaryIndexedTree) lowbit(x int) int {
250+
return x & -x
251+
}
252+
253+
func (this *BinaryIndexedTree) update(x, delta int) {
254+
for x <= this.n {
255+
this.c[x] += delta
256+
x += this.lowbit(x)
257+
}
258+
}
259+
260+
func (this *BinaryIndexedTree) query(x int) int {
261+
s := 0
262+
for x > 0 {
263+
s += this.c[x]
264+
x -= this.lowbit(x)
265+
}
266+
return s
267+
}
268+
269+
func countRangeSum(nums []int, lower int, upper int) int {
270+
n := len(nums)
271+
presum := make([]int, n+1)
272+
for i, v := range nums {
273+
presum[i+1] = presum[i] + v
274+
}
275+
alls := make(map[int]bool)
276+
for _, s := range presum {
277+
alls[s] = true
278+
alls[s-upper] = true
279+
alls[s-lower] = true
130280
}
131-
var alls []int
132-
for v := range s {
133-
alls = append(alls, v)
281+
var t []int
282+
for s, _ := range alls {
283+
t = append(t, s)
134284
}
135-
sort.Ints(alls)
285+
sort.Ints(t)
136286
m := make(map[int]int)
137-
for i, v := range alls {
287+
for i, v := range t {
138288
m[v] = i + 1
139289
}
140-
var ans []int
141-
for _, v := range arr {
142-
ans = append(ans, m[v])
290+
ans := 0
291+
tree := newBinaryIndexedTree(len(alls))
292+
for _, s := range presum {
293+
i, j := m[s-upper], m[s-lower]
294+
ans += tree.query(j) - tree.query(i-1)
295+
tree.update(m[s], 1)
143296
}
144297
return ans
145298
}

0 commit comments

Comments
 (0)