class Solution {
public:
string smallestStringWithSwaps(string s, vector<vector<int>>& pairs) {
}
};
1202. 交换字符串中的元素
给你一个字符串 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"
提示:
1 <= s.length <= 10^5
0 <= pairs.length <= 10^5
0 <= pairs[i][0], pairs[i][1] < s.length
s
中只含有小写英文字母原站题解
java 解法, 执行用时: 42 ms, 内存消耗: 91.5 MB, 提交时间: 2023-06-06 10:09:35
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<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)); } 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[] f; int[] rank; int n; 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; } } 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]) { int temp = fx; fx = fy; fy = temp; } rank[fx] += rank[fy]; f[fy] = fx; } }
golang 解法, 执行用时: 92 ms, 内存消耗: 18.3 MB, 提交时间: 2023-06-06 10:09:20
func smallestStringWithSwaps(s string, pairs [][]int) string { n := len(s) fa := make([]int, n) rank := make([]int, n) for i := range fa { fa[i] = i rank[i] = 1 } var find func(int) int find = func(x int) int { if fa[x] != x { fa[x] = find(fa[x]) } return fa[x] } union := func(x, y int) { fx, fy := find(x), find(y) if fx == fy { return } if rank[fx] < rank[fy] { fx, fy = fy, fx } rank[fx] += rank[fy] fa[fy] = fx } for _, p := range pairs { union(p[0], p[1]) } groups := map[int][]byte{} for i := range s { f := find(i) groups[f] = append(groups[f], s[i]) } for _, bytes := range groups { sort.Slice(bytes, func(i, j int) bool { return bytes[i] < bytes[j] }) } ans := make([]byte, n) for i := range ans { f := find(i) ans[i] = groups[f][0] groups[f] = groups[f][1:] } return string(ans) }
javascript 解法, 执行用时: 204 ms, 内存消耗: 74.6 MB, 提交时间: 2023-06-06 10:08:55
/** * @param {string} s * @param {number[][]} pairs * @return {string} */ var smallestStringWithSwaps = function(s, pairs) { const fa = new Array(100010).fill(0); const find = (x) => { return x === fa[x] ? x : fa[x] = find(fa[x]); } const n = s.length; for (let i = 0; i < n; i++) { fa[i] = i; } for (let i = 0; i < pairs.length; ++i) { const x = pairs[i][0], y = pairs[i][1]; const ux = find(x), uy = find(y); if (ux ^ uy) { fa[ux] = uy; } } const vec = new Array(n).fill(0).map(() => new Array()); for (let i = 0; i < n; i++) { fa[i] = find(i); vec[fa[i]].push(s[i]); } for (let i = 0; i < n; ++i) { if (vec[i].length > 0) { vec[i].sort((a, b) => a.charCodeAt() - b.charCodeAt()); } } const p = new Array(n).fill(0); let ans = []; for (let i = 0; i < n; ++i) { ans.push('1'); } for (let i = 0; i < n; ++i) { ans[i] = vec[fa[i]][p[fa[i]]]; p[fa[i]]++; } return ans.join(''); };
python3 解法, 执行用时: 244 ms, 内存消耗: 40.8 MB, 提交时间: 2023-06-06 10:08:40
# 并查集 class DisjointSetUnion: def __init__(self, n: int): self.n = n self.rank = [1] * n self.f = list(range(n)) def find(self, x: int) -> int: if self.f[x] == x: return x self.f[x] = self.find(self.f[x]) return self.f[x] def unionSet(self, x: int, y: int): fx, fy = self.find(x), self.find(y) if fx == fy: return if self.rank[fx] < self.rank[fy]: fx, fy = fy, fx self.rank[fx] += self.rank[fy] self.f[fy] = fx class Solution: def smallestStringWithSwaps(self, s: str, pairs: List[List[int]]) -> str: dsu = DisjointSetUnion(len(s)) for x, y in pairs: dsu.unionSet(x, y) mp = collections.defaultdict(list) for i, ch in enumerate(s): mp[dsu.find(i)].append(ch) for vec in mp.values(): vec.sort(reverse=True) ans = list() for i in range(len(s)): x = dsu.find(i) ans.append(mp[x][-1]) mp[x].pop() return "".join(ans)