[路飞]_leetcode-1202-交换字符串中的元素

545 阅读1分钟

题目描述

[题目地址]

给你一个字符串 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.交换;2.按字典排序;3.拼接字符串
  • 1.根据这个二维数组pairs,获取可以交换的字母,然后可以交换的字母组成一组。
  • 2.对组内的字母进行排序。
  • 3.接着根据字符串中组号获取我们组内最小字符进行拼接。最后得到的字符串就是所需要的进行排过序的字符串

动画演示

leetcode-1202-交换字符串中的元素.gif

代码实现:

var smallestStringWithSwaps = function(s, pairs) {
    let len = s.length;
    let uf = new UnionFind(len);
    // 1.将可以进行交换的字符进行连通
    for(let i = 0; i < pairs.length; i ++){//选拿到索引对,遍历数组
        // 拿到里面的每一对数组
        let index1 = pairs[i][0],index2 = pairs[i][1];
        // 拿到两个索引,进行联通
        if(uf.findSet(index1) != uf.findSet(index2)){
            uf.unite(index1,index2);
        }
    }
    // 2.先拿到联通后的数组
    let fa = uf.parent;
    // 2.将联通的字符存入到一个新的数组里面进行排序
    let vec = new Array(len).fill(0).map(()=> new Array());//根据祖先节点进行分组,val 是组里面字符串的集合
    for(let i = 0; i < len; i++){
        fa[i] = uf.findSet(i);
        vec[fa[i]].push(s[i]);
    }
    for(let i = 0; i < len; i++){ // 按着字典序排序
        if(vec[i].length > 0 ){
            vec[i].sort((a,b) => a.charCodeAt() - b.charCodeAt())
        }
    }
    // 3.通过原始字符坐标,获取字符串的组号,拼接字符串
    // 记录每一组字符串位置
    let p = new Array(len).fill(0);
    // 输出字符的数组
    let ans = [];
    for(let i = 0; i < len; i++){
        ans.push('1');
    }
    // 通过原始字符坐标,获取字符串的组号,拼接字符串
    for(let i = 0 ; i < len; i++){
        ans[i] = vec[fa[i]][p[fa[i]]];
        p[fa[i]] ++;
    }
    // 拼接字符join
    return ans.join('');


};

class UnionFind{
    constructor(n){
        this.parent = new Array(n).fill(0).map((val,index)=>index);
        this.rank = new Array(n).fill(0);
        this.setCount = n;
    }

    findSet(index){
        if(this.parent[index] != index){
            this.parent[index] = this.findSet(this.parent[index])
        }
        return this.parent[index];
    }
    unite(index1,index2){
        let root1 = this.findSet(index1);
        let root2 = this.findSet(index2);
        if(root1 != root2){
            if(root1 < root2){
                [root1,root2] = [root2,root1];
            }
            this.parent[root2] = root1;
            this.rank[root1] += this.rank[root2];
            this.setCount--;
        }
    }
    getCount(){
         return this.setCount()
    }
    connected(index1,index2){
        let root1 = this.findSet(index1),root2 = this.findSet(index2);
        return root1 == root2
    }
}

至此我们就完成了leetcode-1202-交换字符串中的元素