Skip to content

Commit e072993

Browse files
committed
feat: add solutions to lc problem: No.0315
No.0315.Count of Smaller Numbers After Self
1 parent da8ccaa commit e072993

File tree

2 files changed

+470
-2
lines changed

2 files changed

+470
-2
lines changed

solution/0300-0399/0315.Count of Smaller Numbers After Self/README.md

Lines changed: 237 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949

5050
<!-- 这里可写通用的实现逻辑 -->
5151

52-
树状数组
52+
**方法一:树状数组**
5353

5454
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
5555

@@ -64,12 +64,16 @@
6464

6565
解决方案是直接遍历数组,每个位置先求出 `query(a[i])`,然后再修改树状数组 `update(a[i], 1)` 即可。当数的范围比较大时,需要进行离散化,即先进行去重并排序,然后对每个数字进行编号。
6666

67+
**方法二:线段树**
68+
6769
<!-- tabs:start -->
6870

6971
### **Python3**
7072

7173
<!-- 这里可写当前语言的特殊实现逻辑 -->
7274

75+
树状数组:
76+
7377
```python
7478
class BinaryIndexedTree:
7579
def __init__(self, n):
@@ -106,10 +110,73 @@ class Solution:
106110
return ans[::-1]
107111
```
108112

113+
线段树:
114+
115+
```python
116+
class Node:
117+
def __init__(self):
118+
self.l = 0
119+
self.r = 0
120+
self.v = 0
121+
122+
class SegmentTree:
123+
def __init__(self, n):
124+
self.tr = [Node() for _ in range(4 * n)]
125+
self.build(1, 1, n)
126+
127+
def build(self, u, l, r):
128+
self.tr[u].l = l
129+
self.tr[u].r = r
130+
if l == r:
131+
return
132+
mid = (l + r) >> 1
133+
self.build(u << 1, l, mid)
134+
self.build(u << 1 | 1, mid + 1, r)
135+
136+
def modify(self, u, x, v):
137+
if self.tr[u].l == x and self.tr[u].r == x:
138+
self.tr[u].v += v
139+
return
140+
mid = (self.tr[u].l + self.tr[u].r) >> 1
141+
if x <= mid:
142+
self.modify(u << 1, x, v)
143+
else:
144+
self.modify(u << 1 | 1, x, v)
145+
self.pushup(u)
146+
147+
def pushup(self, u):
148+
self.tr[u].v = self.tr[u << 1].v + self.tr[u << 1 | 1].v
149+
150+
def query(self, u, l, r):
151+
if self.tr[u].l >= l and self.tr[u].r <= r:
152+
return self.tr[u].v
153+
mid = (self.tr[u].l + self.tr[u].r) >> 1
154+
v = 0
155+
if l <= mid:
156+
v += self.query(u << 1, l, r)
157+
if r > mid:
158+
v += self.query(u << 1 | 1, l, r)
159+
return v
160+
161+
class Solution:
162+
def countSmaller(self, nums: List[int]) -> List[int]:
163+
s = sorted(set(nums))
164+
m = {v: i for i, v in enumerate(s, 1)}
165+
tree = SegmentTree(len(s))
166+
ans = []
167+
for v in nums[::-1]:
168+
x = m[v]
169+
ans.append(tree.query(1, 1, x - 1))
170+
tree.modify(1, x, 1)
171+
return ans[::-1]
172+
```
173+
109174
### **Java**
110175

111176
<!-- 这里可写当前语言的特殊实现逻辑 -->
112177

178+
树状数组:
179+
113180
```java
114181
class Solution {
115182
public List<Integer> countSmaller(int[] nums) {
@@ -166,8 +233,100 @@ class BinaryIndexedTree {
166233
}
167234
```
168235

236+
线段树:
237+
238+
```java
239+
class Solution {
240+
public List<Integer> countSmaller(int[] nums) {
241+
Set<Integer> s = new HashSet<>();
242+
for (int v : nums) {
243+
s.add(v);
244+
}
245+
List<Integer> alls = new ArrayList<>(s);
246+
alls.sort(Comparator.comparingInt(a -> a));
247+
int n = alls.size();
248+
Map<Integer, Integer> m = new HashMap<>(n);
249+
for (int i = 0; i < n; ++i) {
250+
m.put(alls.get(i), i + 1);
251+
}
252+
SegmentTree tree = new SegmentTree(n);
253+
LinkedList<Integer> ans = new LinkedList<>();
254+
for (int i = nums.length - 1; i >= 0; --i) {
255+
int x = m.get(nums[i]);
256+
tree.modify(1, x, 1);
257+
ans.addFirst(tree.query(1, 1, x - 1));
258+
}
259+
return ans;
260+
}
261+
}
262+
263+
class Node {
264+
int l;
265+
int r;
266+
int v;
267+
}
268+
269+
class SegmentTree {
270+
private Node[] tr;
271+
272+
public SegmentTree(int n) {
273+
tr = new Node[4 * n];
274+
for (int i = 0; i < tr.length; ++i) {
275+
tr[i] = new Node();
276+
}
277+
build(1, 1, n);
278+
}
279+
280+
public void build(int u, int l, int r) {
281+
tr[u].l = l;
282+
tr[u].r = r;
283+
if (l == r) {
284+
return;
285+
}
286+
int mid = (l + r) >> 1;
287+
build(u << 1, l, mid);
288+
build(u << 1 | 1, mid + 1, r);
289+
}
290+
291+
public void modify(int u, int x, int v) {
292+
if (tr[u].l == x && tr[u].r == x) {
293+
tr[u].v += v;
294+
return;
295+
}
296+
int mid = (tr[u].l + tr[u].r) >> 1;
297+
if (x <= mid) {
298+
modify(u << 1, x, v);
299+
} else {
300+
modify(u << 1 | 1, x, v);
301+
}
302+
pushup(u);
303+
}
304+
305+
public void pushup(int u) {
306+
tr[u].v = tr[u << 1].v + tr[u << 1 | 1].v;
307+
}
308+
309+
public int query(int u, int l, int r) {
310+
if (tr[u].l >= l && tr[u].r <= r) {
311+
return tr[u].v;
312+
}
313+
int mid = (tr[u].l + tr[u].r) >> 1;
314+
int v = 0;
315+
if (l <= mid) {
316+
v += query(u << 1, l, r);
317+
}
318+
if (r > mid) {
319+
v += query(u << 1 | 1, l, r);
320+
}
321+
return v;
322+
}
323+
}
324+
```
325+
169326
### **C++**
170327

328+
树状数组:
329+
171330
```cpp
172331
class BinaryIndexedTree {
173332
public:
@@ -221,6 +380,83 @@ public:
221380
};
222381
```
223382
383+
线段树:
384+
385+
```cpp
386+
class Node {
387+
public:
388+
int l;
389+
int r;
390+
int v;
391+
};
392+
393+
class SegmentTree {
394+
public:
395+
vector<Node*> tr;
396+
397+
SegmentTree(int n) {
398+
tr.resize(4 * n);
399+
for (int i = 0; i < tr.size(); ++i) tr[i] = new Node();
400+
build(1, 1, n);
401+
}
402+
403+
void build(int u, int l, int r) {
404+
tr[u]->l = l;
405+
tr[u]->r = r;
406+
if (l == r) return;
407+
int mid = (l + r) >> 1;
408+
build(u << 1, l, mid);
409+
build(u << 1 | 1, mid + 1, r);
410+
}
411+
412+
void modify(int u, int x, int v) {
413+
if (tr[u]->l == x && tr[u]->r == x)
414+
{
415+
tr[u]->v += v;
416+
return;
417+
}
418+
int mid = (tr[u]->l + tr[u]->r) >> 1;
419+
if (x <= mid) modify(u << 1, x, v);
420+
else modify(u << 1 | 1, x, v);
421+
pushup(u);
422+
}
423+
424+
void pushup(int u) {
425+
tr[u]->v = tr[u << 1]->v + tr[u << 1 | 1]->v;
426+
}
427+
428+
int query(int u, int l, int r) {
429+
if (tr[u]->l >= l && tr[u]->r <= r) return tr[u]->v;
430+
int mid = (tr[u]->l + tr[u]->r) >> 1;
431+
int v = 0;
432+
if (l <= mid) v += query(u << 1, l, r);
433+
if (r > mid) v += query(u << 1 | 1, l, r);
434+
return v;
435+
}
436+
};
437+
438+
class Solution {
439+
public:
440+
vector<int> countSmaller(vector<int>& nums) {
441+
unordered_set<int> s(nums.begin(), nums.end());
442+
vector<int> alls(s.begin(), s.end());
443+
sort(alls.begin(), alls.end());
444+
unordered_map<int, int> m;
445+
int n = alls.size();
446+
for (int i = 0; i < n; ++i) m[alls[i]] = i + 1;
447+
SegmentTree* tree = new SegmentTree(n);
448+
vector<int> ans(nums.size());
449+
for (int i = nums.size() - 1; i >= 0; --i)
450+
{
451+
int x = m[nums[i]];
452+
tree->modify(1, x, 1);
453+
ans[i] = tree->query(1, 1, x - 1);
454+
}
455+
return ans;
456+
}
457+
};
458+
```
459+
224460
### **Go**
225461

226462
```go

0 commit comments

Comments
 (0)