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.
Example 1:
Input: s = "dcab", pairs = [[0,3],[1,2]] Output: "bacd" Explaination: Swap s[0] and s[3], s = "bcad" Swap s[1] and s[2], s = "bacd"
Example 2:
Input: s = "dcab", pairs = [[0,3],[1,2],[0,2]] Output: "abcd" Explaination: Swap s[0] and s[3], s = "bcad" Swap s[0] and s[2], s = "acbd" Swap s[1] and s[2], s = "abcd"
Example 3:
Input: s = "cba", pairs = [[0,1],[1,2]] Output: "abc" Explaination: Swap s[0] and s[1], s = "bca" Swap s[1] and s[2], s = "bac" Swap s[0] and s[1], s = "abc"
Constraints:
1 <= s.length <= 10^5
0 <= pairs.length <= 10^5
0 <= pairs[i][0], pairs[i][1] < s.length
s
only contains lower case English letters.
Solution: Connected Components
Use DFS / Union-Find to find all the connected components of swapable indices. For each connected components (index group), extract the subsequence of corresponding chars as a string, sort it and put it back to the original string in the same location.
e.g. s = “dcab”, pairs = [[0,3],[1,2]]
There are two connected components: {0,3}, {1,2}
subsequences:
1. 0,3 “db”, sorted: “bd”
2. 1,2 “ca”, sorted: “ac”
0 => b
1 => a
2 => c
3 => d
final = “bacd”
Time complexity: DFS: O(nlogn + k*(V+E)), Union-Find: O(nlogn + V+E)
Space complexity: O(n)
C++/DFS
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 |
// Author: Huahua, 268 ms, 89 MB class Solution { public: string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) { vector<vector<int>> g(s.length()); for (const auto& e : pairs) { g[e[0]].push_back(e[1]); g[e[1]].push_back(e[0]); } unordered_set<int> seen; vector<int> idx; string tmp; function<void(int)> dfs = [&](int cur) { if (seen.count(cur)) return; seen.insert(cur); idx.push_back(cur); tmp += s[cur]; for (int nxt : g[cur]) dfs(nxt); }; for (int i = 0; i < s.length(); ++i) { if (seen.count(i)) continue; idx.clear(); tmp.clear(); dfs(i); sort(begin(tmp), end(tmp)); sort(begin(idx), end(idx)); for (int k = 0; k < idx.size(); ++k) s[idx[k]] = tmp[k]; } return s; } }; |
C++/Union-Find
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 |
// Author: Huahua, 152 ms, 48.2 MB class Solution { public: string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) { int n = s.length(); vector<int> p(n); iota(begin(p), end(p), 0); // p = {0, 1, 2, ... n - 1} function<int(int)> find = [&](int x) { return p[x] == x ? x : p[x] = find(p[x]); }; for (const auto& e : pairs) p[find(e[0])] = find(e[1]); // union vector<vector<int>> idx(n); vector<string> ss(n); for (int i = 0; i < s.length(); ++i) { int id = find(i); idx[id].push_back(i); // already sorted ss[id].push_back(s[i]); } for (int i = 0; i < n; ++i) { sort(begin(ss[i]), end(ss[i])); for (int k = 0; k < idx[i].size(); ++k) s[idx[i][k]] = ss[i][k]; } return s; } }; |
请尊重作者的劳动成果,转载请注明出处!花花保留对文章/视频的所有权利。
如果您喜欢这篇文章/视频,欢迎您捐赠花花。
If you like my articles / videos, donations are welcome.
Be First to Comment