Skip to content

Commit 4607d34

Browse files
committed
feat: add solutions to lc problem: No.0493
No.0493.Reverse Pairs
1 parent d453d50 commit 4607d34

File tree

2 files changed

+483
-1
lines changed

2 files changed

+483
-1
lines changed

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

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252

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

55+
**方法三:线段树**
56+
5557
<!-- tabs:start -->
5658

5759
### **Python3**
@@ -139,6 +141,72 @@ class Solution:
139141
return ans
140142
```
141143

144+
线段树:
145+
146+
```python
147+
class Node:
148+
def __init__(self):
149+
self.l = 0
150+
self.r = 0
151+
self.v = 0
152+
153+
class SegmentTree:
154+
def __init__(self, n):
155+
self.tr = [Node() for _ in range(4 * n)]
156+
self.build(1, 1, n)
157+
158+
def build(self, u, l, r):
159+
self.tr[u].l = l
160+
self.tr[u].r = r
161+
if l == r:
162+
return
163+
mid = (l + r) >> 1
164+
self.build(u << 1, l, mid)
165+
self.build(u << 1 | 1, mid + 1, r)
166+
167+
def modify(self, u, x, v):
168+
if self.tr[u].l == x and self.tr[u].r == x:
169+
self.tr[u].v += 1
170+
return
171+
mid = (self.tr[u].l + self.tr[u].r) >> 1
172+
if x <= mid:
173+
self.modify(u << 1, x, v)
174+
else:
175+
self.modify(u << 1 | 1, x, v)
176+
self.pushup(u)
177+
178+
def pushup(self, u):
179+
self.tr[u].v = self.tr[u << 1].v + self.tr[u << 1 | 1].v
180+
181+
def query(self, u, l, r):
182+
if self.tr[u].l >= l and self.tr[u].r <= r:
183+
return self.tr[u].v
184+
mid = (self.tr[u].l + self.tr[u].r) >> 1
185+
v = 0
186+
if l <= mid:
187+
v += self.query(u << 1, l, r)
188+
if r > mid:
189+
v += self.query(u << 1 | 1, l, r)
190+
return v
191+
192+
193+
class Solution:
194+
def reversePairs(self, nums: List[int]) -> int:
195+
s = set()
196+
for num in nums:
197+
s.add(num)
198+
s.add(num * 2)
199+
alls = sorted(s)
200+
m = {v: i for i, v in enumerate(alls, 1)}
201+
tree = SegmentTree(len(m))
202+
ans = 0
203+
for v in nums[::-1]:
204+
x = m[v]
205+
ans += tree.query(1, 1, x - 1)
206+
tree.modify(1, m[v * 2], 1)
207+
return ans
208+
```
209+
142210
### **Java**
143211

144212
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -248,6 +316,95 @@ class BinaryIndexedTree {
248316
}
249317
```
250318

319+
线段树:
320+
321+
```java
322+
class Solution {
323+
public int reversePairs(int[] nums) {
324+
TreeSet<Long> ts = new TreeSet<>();
325+
for (int num : nums) {
326+
ts.add((long) num);
327+
ts.add((long) num * 2);
328+
}
329+
Map<Long, Integer> m = new HashMap<>();
330+
int idx = 0;
331+
for (long num : ts) {
332+
m.put(num, ++idx);
333+
}
334+
SegmentTree tree = new SegmentTree(m.size());
335+
int ans = 0;
336+
for (int i = nums.length - 1; i >= 0; --i) {
337+
int x = m.get((long) nums[i]);
338+
ans += tree.query(1, 1, x - 1);
339+
tree.modify(1, m.get((long) nums[i] * 2), 1);
340+
}
341+
return ans;
342+
}
343+
}
344+
345+
class Node {
346+
int l;
347+
int r;
348+
int v;
349+
}
350+
351+
class SegmentTree {
352+
private Node[] tr;
353+
354+
public SegmentTree(int n) {
355+
tr = new Node[4 * n];
356+
for (int i = 0; i < tr.length; ++i) {
357+
tr[i] = new Node();
358+
}
359+
build(1, 1, n);
360+
}
361+
362+
public void build(int u, int l, int r) {
363+
tr[u].l = l;
364+
tr[u].r = r;
365+
if (l == r) {
366+
return;
367+
}
368+
int mid = (l + r) >> 1;
369+
build(u << 1, l, mid);
370+
build(u << 1 | 1, mid + 1, r);
371+
}
372+
373+
public void modify(int u, int x, int v) {
374+
if (tr[u].l == x && tr[u].r == x) {
375+
tr[u].v += v;
376+
return;
377+
}
378+
int mid = (tr[u].l + tr[u].r) >> 1;
379+
if (x <= mid) {
380+
modify(u << 1, x, v);
381+
} else {
382+
modify(u << 1 | 1, x, v);
383+
}
384+
pushup(u);
385+
}
386+
387+
public void pushup(int u) {
388+
tr[u].v = tr[u << 1].v + tr[u << 1 | 1].v;
389+
}
390+
391+
public int query(int u, int l, int r) {
392+
if (tr[u].l >= l && tr[u].r <= r) {
393+
return tr[u].v;
394+
}
395+
int mid = (tr[u].l + tr[u].r) >> 1;
396+
int v = 0;
397+
if (l <= mid) {
398+
v += query(u << 1, l, r);
399+
}
400+
if (r > mid) {
401+
v += query(u << 1 | 1, l, r);
402+
}
403+
return v;
404+
}
405+
}
406+
```
407+
251408
### **C++**
252409

253410
归并排序:
@@ -351,6 +508,85 @@ public:
351508
};
352509
```
353510

511+
线段树:
512+
513+
```cpp
514+
class Node {
515+
public:
516+
int l;
517+
int r;
518+
int v;
519+
};
520+
521+
class SegmentTree {
522+
public:
523+
vector<Node*> tr;
524+
525+
SegmentTree(int n) {
526+
tr.resize(4 * n);
527+
for (int i = 0; i < tr.size(); ++i) tr[i] = new Node();
528+
build(1, 1, n);
529+
}
530+
531+
void build(int u, int l, int r) {
532+
tr[u]->l = l;
533+
tr[u]->r = r;
534+
if (l == r) return;
535+
int mid = (l + r) >> 1;
536+
build(u << 1, l, mid);
537+
build(u << 1 | 1, mid + 1, r);
538+
}
539+
540+
void modify(int u, int x, int v) {
541+
if (tr[u]->l == x && tr[u]->r == x)
542+
{
543+
tr[u]->v += v;
544+
return;
545+
}
546+
int mid = (tr[u]->l + tr[u]->r) >> 1;
547+
if (x <= mid) modify(u << 1, x, v);
548+
else modify(u << 1 | 1, x, v);
549+
pushup(u);
550+
}
551+
552+
void pushup(int u) {
553+
tr[u]->v = tr[u << 1]->v + tr[u << 1 | 1]->v;
554+
}
555+
556+
int query(int u, int l, int r) {
557+
if (tr[u]->l >= l && tr[u]->r <= r) return tr[u]->v;
558+
int mid = (tr[u]->l + tr[u]->r) >> 1;
559+
int v = 0;
560+
if (l <= mid) v = query(u << 1, l, r);
561+
if (r > mid) v += query(u << 1 | 1, l, r);
562+
return v;
563+
}
564+
};
565+
566+
class Solution {
567+
public:
568+
int reversePairs(vector<int>& nums) {
569+
set<long long> s;
570+
for (int num : nums)
571+
{
572+
s.insert(num);
573+
s.insert(num * 2ll);
574+
}
575+
unordered_map<long long, int> m;
576+
int idx = 0;
577+
for (long long num : s) m[num] = ++idx;
578+
SegmentTree* tree = new SegmentTree(m.size());
579+
int ans = 0;
580+
for (int i = nums.size() - 1; i >= 0; --i)
581+
{
582+
ans += tree->query(1, 1, m[nums[i]] - 1);
583+
tree->modify(1, m[nums[i] * 2ll], 1);
584+
}
585+
return ans;
586+
}
587+
};
588+
```
589+
354590
### **Go**
355591
356592
归并排序:

0 commit comments

Comments
 (0)