题目描述
给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。
你可以 任意多次交换 在 pairs 中任意一对索引处的字符。
返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。
示例 1:
输入:s = "dcab", pairs = [[0,3],[1,2]]
输出:"bacd"
解释:
交换 s[0] 和 s[3], s = "bcad"
交换 s[1] 和 s[2], s = "bacd"
示例 2:
输入:s = "dcab", pairs = [[0,3],[1,2],[0,2]]
输出:"abcd"
解释:
交换 s[0] 和 s[3], s = "bcad"
交换 s[0] 和 s[2], s = "acbd"
交换 s[1] 和 s[2], s = "abcd"
示例 3:
输入:s = "cba", pairs = [[0,1],[1,2]]
输出:"abc"
解释:
交换 s[0] 和 s[1], s = "bca"
交换 s[1] 和 s[2], s = "bac"
交换 s[0] 和 s[1], s = "abc"
解题思路
该题需要回炉,看题解才能理解
考察并查集--将可以间接连通的字母并为一个集合,然后将其按升序排列。这样便可以实现整体的字典序升序(因为子连通内可任意交换,可以达到最后升序)
运行结果
java代码参考题解
class Solution {
public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
//初始化连通图
DisjointSetUnion dsu = new DisjointSetUnion(s.length());
for(List<Integer> pair:pairs){
//合并
dsu.unionSet(pair.get(0),pair.get(1));
}
//使用map存储祖先节点到子节点列表的映射,存储并查集结果
//例如s = "dcab", pairs = [[0,3],[1,2]]
//0:[d,b] 1:[c,a]
Map<Integer,List<Character>> map =new HashMap<Integer,List<Character>>();
for(int i =0;i<s.length();i++){
int parent = dsu.find(i);//找到该节点的父节点
if(!map.containsKey(parent)){
map.put(parent,new ArrayList<Character>());
}
map.get(parent).add(s.charAt(i));
}//将同意祖先节点下的子节点放在一起
//对map中的值进行排序=降序
for(Map.Entry<Integer,List<Character>> entry:map.entrySet()){
Collections.sort(entry.getValue(),new Comparator<Character>(){
public int compare(Character c1,Character c2){
return c2-c1;
}
});
}
StringBuffer sb = new StringBuffer();
for(int i =0;i<s.length();i++){
int x = dsu.find(i);
List<Character> list =map.get(x);
sb.append(list.remove(list.size()-1));
}//从头到尾,每次放入子连通中的较小的那个
return sb.toString();
}
}
//定义并差集类
class DisjointSetUnion{
int n; //并查集长度
int[] rank; //节点等级
int[] f; //存储对应的祖先节点
//构造函数,初始化属性
public DisjointSetUnion(int n){
this.n = n;
rank = new int[n];
Arrays.fill(rank,1);
f = new int[n];
for(int i=0;i<n;i++){
f[i] = i;
}
}
//方法find,寻找给节点的祖先
public int find(int x){
return f[x] == x?x:(f[x]=find(f[x]));
}
//合并到一个图***同有一个祖先
public void unionSet(int x, int y) {
int fx=find(x),fy = find(y);
if(fx==fy){
return;
}
if(rank[fx]<rank[fy]){
//swap(fx,fy);
int temp = fx;
fx=fy;
fy=temp;
}
//fx级别高,要作为祖先
rank[fx] +=rank[fy];
f[fy] = fx;
}
}
京公网安备 11010502036488号