题目
给你一个字符串 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 中只含有小写英文字母
解题思路分析
1、并查集+排序;时间复杂度O(nlog(n)),空间复杂度O(n)
func smallestStringWithSwaps(s string, pairs [][]int) string {n := len(s)fa := make([]int, n)for i := 0; i < n; i++ {fa[i] = i}for i := 0; i < len(pairs); i++ {a, b := pairs[i][0], pairs[i][1]union(fa, a, b)}m := make(map[int][]int)for i := 0; i < len(s); i++ {target := find(fa, i)m[target] = append(m[target], i)}res := []byte(s)for _, v := range m {arr := make([]int, 0)for i := 0; i < len(v); i++ {arr = append(arr, int(s[v[i]]))}sort.Ints(arr)for i := 0; i < len(v); i++ {res[v[i]] = byte(arr[i])}}return string(res)}func union(fa []int, a, b int) {fa[find(fa, a)] = find(fa, b)}func find(fa []int, a int) int {for fa[a] != a {fa[a] = fa[fa[a]]a = fa[a]}return a}
总结
Medium题目,使用并查集分组,然后分组排序即可