题意
给定一些可以任意交换位置的组, 求整个字符串的最小字典序
思路
- 用并查集把所有组关联在一起
- 对于每个可交换组, 把所有候选字母依次填入
收获
- unordered_map的使用
- c++的for-range语法
1 2 3
| for(auto&[i,group]:groups){ sort(group.begin(),group.end(),greater()); }
|
- 重温并查集
代码
参考官方题解优化完毕
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
| class Solution { public: vector<int>parents,rank; int dj_root(int i){ return (parents[i]==i ? i : parents[i]=dj_root(parents[i])); } void dj_union(int a, int b){ a=dj_root(a); b=dj_root(b); if(a==b)return; if (rank[a]<rank[b])swap(a,b); rank[a]+=rank[b]; parents[a]=b; } string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) { int n=s.size(); parents.resize(n); rank.resize(n,1); for(int i=0;i<n;i++){ parents[i]=i; } for(auto&&pair:pairs){ dj_union(pair[0],pair[1]); }
unordered_map<int,string>groups; for(int i=0;i<n;i++){ int r=dj_root(i); groups[r].push_back(s[i]); }
for(auto&[i,group]:groups){ sort(group.begin(),group.end(),greater()); }
for(int i=0;i<n;i++){ int g=dj_root(i); s[i]=groups[g].back(); groups[g].pop_back(); }
return s; } };
|