Skip to content

Commit 988142c

Browse files
committed
feat: add solutions to lc problem: No.1202.Smallest String With Swaps
1 parent 7ccc603 commit 988142c

File tree

4 files changed

+213
-5
lines changed

4 files changed

+213
-5
lines changed

solution/1200-1299/1202.Smallest String With Swaps/README.md

+113-3
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,137 @@
5353
<li><code>s</code>&nbsp;中只含有小写英文字母</li>
5454
</ul>
5555

56-
5756
## 解法
5857

5958
<!-- 这里可写通用的实现逻辑 -->
6059

60+
并查集。
61+
62+
模板 1——朴素并查集:
63+
64+
```python
65+
# 初始化,p存储每个点的父节点
66+
p = list(range(n))
67+
68+
# 返回x的祖宗节点
69+
def find(x):
70+
if p[x] != x:
71+
# 路径压缩
72+
p[x] = find(p[x])
73+
return p[x]
74+
75+
# 合并a和b所在的两个集合
76+
p[find(a)] = find(b)
77+
```
78+
79+
模板 2——维护 size 的并查集:
80+
81+
```python
82+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
83+
p = list(range(n))
84+
size = [1] * n
85+
86+
# 返回x的祖宗节点
87+
def find(x):
88+
if p[x] != x:
89+
# 路径压缩
90+
p[x] = find(p[x])
91+
return p[x]
92+
93+
# 合并a和b所在的两个集合
94+
if find(a) != find(b):
95+
size[find(b)] += size[find(a)]
96+
p[find(a)] = find(b)
97+
```
98+
99+
模板 3——维护到祖宗节点距离的并查集:
100+
101+
```python
102+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
103+
p = list(range(n))
104+
d = [0] * n
105+
106+
# 返回x的祖宗节点
107+
def find(x):
108+
if p[x] != x:
109+
t = find(p[x])
110+
d[x] += d[p[x]]
111+
p[x] = t
112+
return p[x]
113+
114+
# 合并a和b所在的两个集合
115+
p[find(a)] = find(b)
116+
d[find(a)] = distance
117+
```
118+
119+
对于本题,索引对具备传递性。即如果索引对是 `[0,2]`, `[0, 3]`,那么索引 0、2、3 可以进行任意交换。我们可以利用并查集,遍历每个索引对,将其中的两个索引进行合并,得到并查集,连在一起的索引对应的字符按照字典序排列,这里可以利用优先级队列实现。
120+
121+
最后遍历字符串,找到每个字符的根元素,并替换为字典序中对应的字符。
122+
61123
<!-- tabs:start -->
62124

63125
### **Python3**
64126

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

67129
```python
68-
130+
class Solution:
131+
def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
132+
n = len(s)
133+
p = list(range(n))
134+
135+
def find(x):
136+
if p[x] != x:
137+
p[x] = find(p[x])
138+
return p[x]
139+
140+
for a, b in pairs:
141+
p[find(a)] = find(b)
142+
143+
mp = collections.defaultdict(list)
144+
for i in range(n):
145+
heapq.heappush(mp[find(i)], s[i])
146+
chars = list(s)
147+
for i in range(n):
148+
chars[i] = heapq.heappop(mp[find(i)])
149+
return ''.join(chars)
69150
```
70151

71152
### **Java**
72153

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

75156
```java
76-
157+
class Solution {
158+
private int[] p;
159+
160+
public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
161+
int n = s.length();
162+
p = new int[n];
163+
for (int i = 0; i < n; ++i) {
164+
p[i] = i;
165+
}
166+
for (List<Integer> pair : pairs) {
167+
p[find(pair.get(0))] = find(pair.get(1));
168+
}
169+
Map<Integer, PriorityQueue<Character>> mp = new HashMap<>();
170+
char[] chars = s.toCharArray();
171+
for (int i = 0; i < n; ++i) {
172+
mp.computeIfAbsent(find(i), key -> new PriorityQueue<>()).offer(chars[i]);
173+
}
174+
for (int i = 0; i < n; ++i) {
175+
chars[i] = mp.get(find(i)).poll();
176+
}
177+
return new String(chars);
178+
}
179+
180+
private int find(int x) {
181+
if (p[x] != x) {
182+
p[x] = find(p[x]);
183+
}
184+
return p[x];
185+
}
186+
}
77187
```
78188

79189
### **...**

solution/1200-1299/1202.Smallest String With Swaps/README_EN.md

+50-2
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,61 @@ Swap s[0] and s[1], s = &quot;abc&quot;
6060
### **Python3**
6161

6262
```python
63-
63+
class Solution:
64+
def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
65+
n = len(s)
66+
p = list(range(n))
67+
68+
def find(x):
69+
if p[x] != x:
70+
p[x] = find(p[x])
71+
return p[x]
72+
73+
for a, b in pairs:
74+
p[find(a)] = find(b)
75+
76+
mp = collections.defaultdict(list)
77+
for i in range(n):
78+
heapq.heappush(mp[find(i)], s[i])
79+
chars = list(s)
80+
for i in range(n):
81+
chars[i] = heapq.heappop(mp[find(i)])
82+
return ''.join(chars)
6483
```
6584

6685
### **Java**
6786

6887
```java
69-
88+
class Solution {
89+
private int[] p;
90+
91+
public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
92+
int n = s.length();
93+
p = new int[n];
94+
for (int i = 0; i < n; ++i) {
95+
p[i] = i;
96+
}
97+
for (List<Integer> pair : pairs) {
98+
p[find(pair.get(0))] = find(pair.get(1));
99+
}
100+
Map<Integer, PriorityQueue<Character>> mp = new HashMap<>();
101+
char[] chars = s.toCharArray();
102+
for (int i = 0; i < n; ++i) {
103+
mp.computeIfAbsent(find(i), key -> new PriorityQueue<>()).offer(chars[i]);
104+
}
105+
for (int i = 0; i < n; ++i) {
106+
chars[i] = mp.get(find(i)).poll();
107+
}
108+
return new String(chars);
109+
}
110+
111+
private int find(int x) {
112+
if (p[x] != x) {
113+
p[x] = find(p[x]);
114+
}
115+
return p[x];
116+
}
117+
}
70118
```
71119

72120
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class Solution {
2+
private int[] p;
3+
4+
public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
5+
int n = s.length();
6+
p = new int[n];
7+
for (int i = 0; i < n; ++i) {
8+
p[i] = i;
9+
}
10+
for (List<Integer> pair : pairs) {
11+
p[find(pair.get(0))] = find(pair.get(1));
12+
}
13+
Map<Integer, PriorityQueue<Character>> mp = new HashMap<>();
14+
char[] chars = s.toCharArray();
15+
for (int i = 0; i < n; ++i) {
16+
mp.computeIfAbsent(find(i), key -> new PriorityQueue<>()).offer(chars[i]);
17+
}
18+
for (int i = 0; i < n; ++i) {
19+
chars[i] = mp.get(find(i)).poll();
20+
}
21+
return new String(chars);
22+
}
23+
24+
private int find(int x) {
25+
if (p[x] != x) {
26+
p[x] = find(p[x]);
27+
}
28+
return p[x];
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution:
2+
def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str:
3+
n = len(s)
4+
p = list(range(n))
5+
6+
def find(x):
7+
if p[x] != x:
8+
p[x] = find(p[x])
9+
return p[x]
10+
11+
for a, b in pairs:
12+
p[find(a)] = find(b)
13+
14+
mp = collections.defaultdict(list)
15+
for i in range(n):
16+
heapq.heappush(mp[find(i)], s[i])
17+
chars = list(s)
18+
for i in range(n):
19+
chars[i] = heapq.heappop(mp[find(i)])
20+
return ''.join(chars)

0 commit comments

Comments
 (0)