LeetCode的第1202道题目,题目如下:
You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string.
You can swap the characters at any pair of indices in the given pairs any number of times.
Return the lexicographically smallest string that s can be changed to after using the swaps.
这道题的本质在于根据可以交换的元素,可以组成若干个类似朋友圈的结构,朋友圈内部的元素可以互相交换,即可以按照从小到大的顺序进行排列,而朋友圈之间的元素不能交换。因此,首先用并查集结构找到有多少个“朋友圈”,每个“朋友圈”内部的所有字符用优先队列来存储,然后依次取出,即可完成“朋友圈”内部字符的排列。
代码如下:
public class SmallestStringWithSwaps {
public static void main(String[] args){
String s = "dcab";
List<Integer> list = new ArrayList<>();
list.add(0);
list.add(3);
List<List<Integer>> pairs = new ArrayList<>();
pairs.add(list);
list = new ArrayList<>();
list.add(1);
list.add(2);
pairs.add(list);
System.out.println(smallestStringWithSwaps( s, pairs));
}
public static String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
UnionFindSet union = new UnionFindSet(s.length());
for(List<Integer> list : pairs){
int a = list.get(0);
int b = list.get(1);
union.union(a,b);
}
char[] arr = s.toCharArray();
HashMap<Integer, PriorityQueue<Character>> map = new HashMap<>();
for(int i = 0;i < arr.length;i ++){
int key = union.findRoot(i);
if(map.containsKey(key)){
PriorityQueue<Character> q = map.get(key);
q.add(arr[i]);
}
else{
PriorityQueue<Character> q = new PriorityQueue<>();
q.add(arr[i]);
map.put(key,q);
}
}
for(int i = 0;i < arr.length;i ++){
int key = union.findRoot(i);
if(key != -1){
arr[i] = map.get(key).poll();
}
}
return new String(arr);
}
}
class UnionFindSet {
private int[] elements;
private int[] heights;
public UnionFindSet(int n){
elements = new int[n];
heights = new int[n];
Arrays.fill(elements,-1);
Arrays.fill(heights,1);
}
public int findRoot(int i){
while(elements[i] != -1){
i = elements[i];
}
return i;
}
public void union(int x,int y){
int xRoot = findRoot(x);
int yRoot = findRoot(y);
if(xRoot != yRoot){
if(heights[xRoot] > heights[yRoot])
elements[yRoot] = xRoot;
else if(heights[xRoot] < heights[yRoot])
elements[xRoot] = yRoot;
else{
elements[xRoot] = yRoot;
heights[yRoot]++;
}
}
}
}