1202. Smallest String With Swaps

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class Solution {
private static class UnionFind {
private final int[] parent;

public UnionFind(int n) {
this.parent = new int[n];
for (int i = 0; i < parent.length; i++) {
parent[i] = i;
}
}

public void union(int x, int y) {
int xRoot = getRoot(x), yRoot = getRoot(y);
if (xRoot == yRoot) {
return;
}

parent[xRoot] = yRoot;
}

private int getRoot(int x) {
if (x != parent[x]) {
parent[x] = getRoot(parent[x]);
}

return parent[x];
}
}

public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
UnionFind unionFind = new UnionFind(s.length());
for (List<Integer> pair : pairs) {
unionFind.union(pair.get(0), pair.get(1));
}

Map<Integer, Queue<Character>> rootIndexToCharQueueMap = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
int rootIndex = unionFind.getRoot(i);
rootIndexToCharQueueMap.computeIfAbsent(rootIndex, key -> new PriorityQueue<>()).offer(s.charAt(i));
}

StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
int rootIndex = unionFind.getRoot(i);
sb.append(rootIndexToCharQueueMap.get(rootIndex).poll());
}

return sb.toString();
}
}

注意题解未采用边构建并查集边构建集合的方式,而是将并查集构建完成后,扫描一遍字符串构建根节点与节点列表的映射,且此时选择的数据结构为优先队列,因为优先队列有序且支持重复元素,所以此处不能选用 TreeSet。

References

1202. Smallest String With Swaps