1202. Exchange elements in a string
Link: https://leetcode-cn.com/problems/smallest-string-with-swaps/
Give you a string s
and an array of "index pairs" in the string pairs
, which pairs[i] = [a, b]
represent two indexes in the string (numbering starts from 0).
You can swap characters at pairs
any pair of indexes in any number of times .
Return the s
smallest string lexicographically that can become after several exchanges .
Example 1:
输入:s = "dcab", pairs = [[0,3],[1,2]]
输出:"bacd"
解释:
交换 s[0] 和 s[3], s = "bcad"
交换 s[1] 和 s[2], s = "bacd"
Example 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"
Example 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"
prompt:
1 <= s.length <= 10^5
0 <= pairs.length <= 10^5
0 <= pairs[i][0], pairs[i][1] < s.length
s
Contains only lowercase English letters
Idea: The index pair given in the title allows us to exchange as many times as we want. We can find that when there are duplicate elements between two index pairs, then the order between the three elements owned by the two indexes can be exchanged arbitrarily In the same way, the order of the elements occupied by the interconnected index pairs can be exchanged at will; we want the lexicographic order to be the smallest, and naturally require the lexicographic order among the elements that can be exchanged to be the smallest; we regard the elements that can be exchanged Work is a collection, and naturally I think of using and checking to maintain this relationship.
class Solution {
public:
int Father[100010], Rank[100010];
int Find(int x){
if(x != Father[x]){
return Father[x] = Find(Father[x]);
}
return x;
}
void Union(int A,int B){
A = Find(A);
B = Find(B);
if(A != B){
if(Rank[A] < Rank[B]){
Father[A] = B;
}else if(Rank[A] > Rank[B]){
Father[B] = A;
}else{
Father[A] = B;
++ Rank[B];
}
}
}
string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) {
unordered_set<int> Hash_Set;
vector<int> Index[100010];
vector<char> StrChar[100010];
int n = s.length(), i, a, b, m = pairs.size(), index;
for(i = 0; i < n; ++ i){
Father[i] = i;
Rank[i] = 1;
}
for(i = 0; i < m; ++ i){
a = pairs[i][0];
b = pairs[i][1];
cout << "Union : " << a << " " << b << endl;
Union(a, b);
}
for(i = 0; i < n; ++ i){ //统计一共有几个集合
if(Hash_Set.find(Find(i)) == Hash_Set.end()){
Hash_Set.insert(Father[i]);
}
Index[Father[i]].push_back(i);
StrChar[Father[i]].push_back(s[i]);
}
unordered_set<int>::iterator iter;
for(iter = Hash_Set.begin(); iter != Hash_Set.end(); ++ iter){
index = * iter;
m = Index[index].size();
sort(StrChar[index].begin(),StrChar[index].end());
for(i = 0; i < m; ++ i){
s[Index[index][i]] = StrChar[index][i];
}
}
return s;
}
};