Skip to content

Commit d602756

Browse files
committed
[0113]ADD:LC-1202
1 parent 2c37c1d commit d602756

File tree

2 files changed

+97
-1
lines changed

2 files changed

+97
-1
lines changed

Diff for: readme.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[[20210105]830. 较大分组的位置-Easy](字符串/830.%20较大分组的位置-Easy.md)
55
[[20210108]131. 分割回文串-Medium](回溯法/131.%20分割回文串-Medium.md)
66
[[20210108]189. 旋转数组-Medium](189.%20旋转数组-Medium.md)
7+
[[20210113]1202. 交换字符串中的元素-Medium](1202.%20交换字符串中的元素-Medium.md)
78
## 2020.12
89
[[20201201]34. 在排序数组中查找元素的第一个和最后一个位置-Medium](数组/34.%20在排序数组中查找元素的第一个和最后一个位置-Medium.md)
910
[[20201202]292. Nim 游戏-Easy](动态规划/292.%20Nim%20游戏-Easy.md)
@@ -99,7 +100,8 @@
99100

100101
## 并查集
101102
[684. 冗余连接-Medium](并查集/684.%20冗余连接-Medium.md)
102-
[990. 等式方程的可满足性-Medium](并查集/990.%20等式方程的可满足性-Medium.md)
103+
[990. 等式方程的可满足性-Medium](并查集/990.%20等式方程的可满足性-Medium.md)
104+
[1202. 交换字符串中的元素-Medium](1202.%20交换字符串中的元素-Medium.md)
103105

104106
## 链表
105107
[2. 两数相加-Medium](链表/2.%20两数相加-Medium.md)
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# [Description](https://leetcode-cn.com/problems/smallest-string-with-swaps)
2+
给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i][a, b] 表示字符串中的两个索引(编号从 0 开始)。
3+
4+
你可以 任意多次交换 在 pairs 中任意一对索引处的字符。
5+
6+
返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。
7+
8+
 
9+
10+
示例 1:
11+
```python
12+
输入:s = "dcab", pairs = [[0,3],[1,2]]
13+
输出:"bacd"
14+
解释:
15+
交换 s[0] 和 s[3], s = "bcad"
16+
交换 s[1] 和 s[2], s = "bacd"
17+
```
18+
示例 2:
19+
```python
20+
输入:s = "dcab", pairs = [[0,3],[1,2],[0,2]]
21+
输出:"abcd"
22+
解释:
23+
交换 s[0] 和 s[3], s = "bcad"
24+
交换 s[0] 和 s[2], s = "acbd"
25+
交换 s[1] 和 s[2], s = "abcd"
26+
```
27+
示例 3:
28+
```python
29+
输入:s = "cba", pairs = [[0,1],[1,2]]
30+
输出:"abc"
31+
解释:
32+
交换 s[0] 和 s[1], s = "bca"
33+
交换 s[1] 和 s[2], s = "bac"
34+
交换 s[0] 和 s[1], s = "abc"
35+
```
36+
37+
提示:
38+
- 1 <= s.length <= 10^5
39+
- 0 <= pairs.length <= 10^5
40+
- 0 <= pairs[i][0], pairs[i][1] < s.length
41+
- s 中只含有小写英文字母
42+
43+
44+
45+
# Solution
46+
- 主要思路是使用并查集,将可以互换位置的元素聚类
47+
- 对每个类内部的元素进行排序,并按从小到大放回这些元素之前占位的index处
48+
- 注意:并查集中**路径压缩**的小技巧
49+
50+
```python
51+
class UnionFind:
52+
def __init__(self, s):
53+
self.father = {i:i for i in range(len(s))}
54+
55+
def find(self, x):
56+
root = x
57+
58+
while self.father[root] != root:
59+
root = self.father[root]
60+
61+
# 路径压缩
62+
while x != root:
63+
original_father = self.father[x]
64+
self.father[x] = root
65+
x = original_father
66+
67+
return root
68+
69+
def merge(self, x, y):
70+
root_x,root_y = self.find(x),self.find(y)
71+
72+
if root_x != root_y:
73+
self.father[root_x] = root_y
74+
75+
class Solution:
76+
def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
77+
uf = UnionFind(s)
78+
79+
for x, y in pairs:
80+
uf.merge(x, y)
81+
82+
connected_components = collections.defaultdict(list)
83+
for node in range(len(s)):
84+
connected_components[uf.find(node)].append(node)
85+
86+
res = list(s)
87+
for v in connected_components.values():
88+
tmp = [s[i] for i in v]
89+
if len(v) > 1:
90+
tmp.sort()
91+
for i in range(len(v)):
92+
res[v[i]] = tmp[i]
93+
return ''.join(res)
94+
```

0 commit comments

Comments
 (0)