ok
看题:
给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。
你可以 任意多次交换 在 pairs 中任意一对索引处的字符。
返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。
这题,乍一看还以为比较简单,以为按顺序交换就完事,结果,漏看了通过步骤实现字典序最小,也就是不是按照给定顺序,而是自己找一个可以实现字典序最小的顺序,然后执行。
唉,挺难的,并查集,不会。
代码:
class Solution {
public:
int father[100010];
int find(int x)//并查集find
{
return x==father[x]?x:(father[x] = find(father[x]));
}
void merge(int x,int y)//并查集merge
{
father[find(x)] = find(y);
}
string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) {
int n = s.size();
string areastr[100010]; //areastr[x]含义为并查集里所有father==x的结点集合
int cnt[100010] ={0};//cnt[x]含义为areastr[x]内的第一个未分配元素
for(int i=0; i<n; i++) father[i] = i;//初始化并查集
for(auto i: pairs) merge(i[1], i[0]);//merge连通结点
for(int i=0; i<n; i++)
areastr[find(i)]+=s[i];//将s[i]添加到连通结点集合内
for(int i=0; i<n; i++)
sort(areastr[i].begin(),areastr[i].end());//对每个连通图内容排序
for(int i=0; i<n; i++)
s[i] = areastr[father[i]][cnt[find(i)]++];//根据连通图内排序后结果还原字符串
return s;
}
};
很不太ok。