Skip to content

Commit cc76854

Browse files
committed
feat: add solutions to lc problem: No.0493
No.0493.Reverse Pairs
1 parent f1691e3 commit cc76854

File tree

6 files changed

+609
-132
lines changed

6 files changed

+609
-132
lines changed

solution/0400-0499/0493.Reverse Pairs/README.md

+237-1
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,31 @@
3535

3636
<!-- 这里可写通用的实现逻辑 -->
3737

38-
归并排序实现逆序对统计。
38+
**方法一:归并排序**
39+
40+
**方法二:树状数组**
41+
42+
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
43+
44+
1. **单点更新** `update(x, delta)`: 把序列 x 位置的数加上一个值 delta;
45+
1. **前缀和查询** `query(x)`:查询序列 `[1,...x]` 区间的区间和,即位置 x 的前缀和。
46+
47+
这两个操作的时间复杂度均为 `O(log n)`
48+
49+
树状数组最基本的功能就是求比某点 x 小的点的个数(这里的比较是抽象的概念,可以是数的大小、坐标的大小、质量的大小等等)。
50+
51+
比如给定数组 `a[5] = {2, 5, 3, 4, 1}`,求 `b[i] = 位置 i 左边小于等于 a[i] 的数的个数`。对于此例,`b[5] = {0, 1, 1, 2, 0}`
52+
53+
解决方案是直接遍历数组,每个位置先求出 `query(a[i])`,然后再修改树状数组 `update(a[i], 1)` 即可。当数的范围比较大时,需要进行离散化,即先进行去重并排序,然后对每个数字进行编号。
3954

4055
<!-- tabs:start -->
4156

4257
### **Python3**
4358

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

61+
归并排序:
62+
4663
```python
4764
class Solution:
4865
def reversePairs(self, nums: List[int]) -> int:
@@ -81,10 +98,53 @@ class Solution:
8198
return merge_sort(nums, 0, len(nums) - 1)
8299
```
83100

101+
树状数组:
102+
103+
```python
104+
class BinaryIndexedTree:
105+
def __init__(self, n):
106+
self.n = n
107+
self.c = [0] * (n + 1)
108+
109+
@staticmethod
110+
def lowbit(x):
111+
return x & -x
112+
113+
def update(self, x, delta):
114+
while x <= self.n:
115+
self.c[x] += delta
116+
x += BinaryIndexedTree.lowbit(x)
117+
118+
def query(self, x):
119+
s = 0
120+
while x > 0:
121+
s += self.c[x]
122+
x -= BinaryIndexedTree.lowbit(x)
123+
return s
124+
125+
126+
class Solution:
127+
def reversePairs(self, nums: List[int]) -> int:
128+
s = set()
129+
for num in nums:
130+
s.add(num)
131+
s.add(num * 2)
132+
alls = sorted(s)
133+
m = {v: i for i, v in enumerate(alls, 1)}
134+
ans = 0
135+
tree = BinaryIndexedTree(len(m))
136+
for num in nums[::-1]:
137+
ans += tree.query(m[num] - 1)
138+
tree.update(m[num * 2], 1)
139+
return ans
140+
```
141+
84142
### **Java**
85143

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

146+
归并排序:
147+
88148
```java
89149
class Solution {
90150
private static int[] tmp = new int[50010];
@@ -131,8 +191,67 @@ class Solution {
131191
}
132192
```
133193

194+
树状数组:
195+
196+
```java
197+
class Solution {
198+
public int reversePairs(int[] nums) {
199+
TreeSet<Long> ts = new TreeSet<>();
200+
for (int num : nums) {
201+
ts.add((long) num);
202+
ts.add((long) num * 2);
203+
}
204+
Map<Long, Integer> m = new HashMap<>();
205+
int idx = 0;
206+
for (long num : ts) {
207+
m.put(num, ++idx);
208+
}
209+
BinaryIndexedTree tree = new BinaryIndexedTree(m.size());
210+
int ans = 0;
211+
for (int i = nums.length - 1; i >= 0; --i) {
212+
int x = m.get((long) nums[i]);
213+
ans += tree.query(x - 1);
214+
tree.update(m.get((long) nums[i] * 2), 1);
215+
}
216+
return ans;
217+
}
218+
}
219+
220+
class BinaryIndexedTree {
221+
private int n;
222+
private int[] c;
223+
224+
public BinaryIndexedTree(int n) {
225+
this.n = n;
226+
c = new int[n + 1];
227+
}
228+
229+
public void update(int x, int delta) {
230+
while (x <= n) {
231+
c[x] += delta;
232+
x += lowbit(x);
233+
}
234+
}
235+
236+
public int query(int x) {
237+
int s = 0;
238+
while (x > 0) {
239+
s += c[x];
240+
x -= lowbit(x);
241+
}
242+
return s;
243+
}
244+
245+
public static int lowbit(int x) {
246+
return x & -x;
247+
}
248+
}
249+
```
250+
134251
### **C++**
135252

253+
归并排序:
254+
136255
```cpp
137256
class Solution {
138257
public:
@@ -175,8 +294,67 @@ private:
175294
};
176295
```
177296
297+
树状数组:
298+
299+
```cpp
300+
class BinaryIndexedTree {
301+
public:
302+
int n;
303+
vector<int> c;
304+
305+
BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
306+
307+
void update(int x, int delta) {
308+
while (x <= n)
309+
{
310+
c[x] += delta;
311+
x += lowbit(x);
312+
}
313+
}
314+
315+
int query(int x) {
316+
int s = 0;
317+
while (x > 0)
318+
{
319+
s += c[x];
320+
x -= lowbit(x);
321+
}
322+
return s;
323+
}
324+
325+
int lowbit(int x) {
326+
return x & -x;
327+
}
328+
};
329+
330+
class Solution {
331+
public:
332+
int reversePairs(vector<int>& nums) {
333+
set<long long> s;
334+
for (int num : nums)
335+
{
336+
s.insert(num);
337+
s.insert(num * 2ll);
338+
}
339+
unordered_map<long long, int> m;
340+
int idx = 0;
341+
for (long long num : s) m[num] = ++idx;
342+
BinaryIndexedTree* tree = new BinaryIndexedTree(m.size());
343+
int ans = 0;
344+
for (int i = nums.size() - 1; i >= 0; --i)
345+
{
346+
ans += tree->query(m[nums[i]] - 1);
347+
tree->update(m[nums[i] * 2ll], 1);
348+
}
349+
return ans;
350+
}
351+
};
352+
```
353+
178354
### **Go**
179355

356+
归并排序:
357+
180358
```go
181359
func reversePairs(nums []int) int {
182360
return mergeSort(nums, 0, len(nums)-1)
@@ -223,6 +401,64 @@ func mergeSort(nums []int, left, right int) int {
223401
}
224402
```
225403

404+
树状数组:
405+
406+
```go
407+
type BinaryIndexedTree struct {
408+
n int
409+
c []int
410+
}
411+
412+
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
413+
c := make([]int, n+1)
414+
return &BinaryIndexedTree{n, c}
415+
}
416+
417+
func (this *BinaryIndexedTree) lowbit(x int) int {
418+
return x & -x
419+
}
420+
421+
func (this *BinaryIndexedTree) update(x, delta int) {
422+
for x <= this.n {
423+
this.c[x] += delta
424+
x += this.lowbit(x)
425+
}
426+
}
427+
428+
func (this *BinaryIndexedTree) query(x int) int {
429+
s := 0
430+
for x > 0 {
431+
s += this.c[x]
432+
x -= this.lowbit(x)
433+
}
434+
return s
435+
}
436+
437+
func reversePairs(nums []int) int {
438+
s := make(map[int]bool)
439+
for _, num := range nums {
440+
s[num] = true
441+
s[num*2] = true
442+
}
443+
var alls []int
444+
for num := range s {
445+
alls = append(alls, num)
446+
}
447+
sort.Ints(alls)
448+
m := make(map[int]int)
449+
for i, num := range alls {
450+
m[num] = i + 1
451+
}
452+
tree := newBinaryIndexedTree(len(m))
453+
ans := 0
454+
for i := len(nums) - 1; i >= 0; i-- {
455+
ans += tree.query(m[nums[i]] - 1)
456+
tree.update(m[nums[i]*2], 1)
457+
}
458+
return ans
459+
}
460+
```
461+
226462
### **...**
227463

228464
```

0 commit comments

Comments
 (0)