2021-01-11 1202.交换字符串中的元素[并查集]

1202.交换字符串中的元素

首先,我不得不吐槽一下这个题目,我一开始以为是根据Pairs里面的东西进行操作。
实际上,这个题目说的意思就是:

  1. 根据Pairs把放在一起的元素归为1类
  2. 将同类的元素按照从小到达排序。
  3. 输出最后的字符串。

收获:

1. 将String转化为Char的数组: s.toCharArray()

2. 类似Python的字符串诸位构造:StringBuilder和.append()

思路一:并查集

第一步:我们通过并查集把相同的元素合并为一类
第二步:我们利用HashMap,Key是同类元素第一个元素的下标,Value是一个同类元素的PriorityQueue,字符小的在树的顶端,我们构建这样一个Priority Queue。
第三步:我们从小到大遍历String,每次找到他对应的类别,找到其对应类别中最小的元素即可,又因为我们每次移动一个字符,就会从Priority Queue中Pop出一个字符,所以我们输出字符的长度应该和原来字符的长度是一样的。

class Solution {
    
    
    public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
    
    
        if(pairs.size()==0)
            return s;

        // 第一步:利用并查集,将相同的元素合并为1类
        int len = s.length();
        UnionFind uf = new UnionFind(len);
        for(List<Integer> pair : pairs)
            uf.union(pair.get(0),pair.get(1));

        // 将String转化为Char的数组
        char[] charArray = s.toCharArray();

        // 第二步:构建HashMap
        HashMap<Integer,PriorityQueue<Character>> hm = new HashMap<>();
        for(int i=0;i<len;i++){
    
    
            int parenti = uf.find(i);
            // 如果已经键入这个类别了,则找到对应的Pq再添加一个新的元素
            if(hm.containsKey(parenti))
                hm.get(parenti).offer(charArray[i]);
            else{
    
    
                PriorityQueue<Character> tmp = new PriorityQueue<>();
                tmp.add(charArray[i]);
                hm.put(parenti,tmp);
            }
        }

        // 第三部:重组最后的答案字符串
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<len;i++){
    
    
            int parenti = uf.find(i);
            sb.append(hm.get(parenti).poll());
        }

        return sb.toString();
    }
}

class UnionFind{
    
    
    int[] element;
    int[] rank; //真正有用的是父节点

    public UnionFind(int N){
    
    
        this.rank = new int[N];
        this.element = new int[N];
        for(int i=0;i<N;i++)
            this.element[i]=i;
    }

    //带有路径压缩
    public int find(int i){
    
    
        if(element[i]==i)
            return i;
        else{
    
    
            element[i]=find(element[i]);
        }
        return element[i];
    }

    public void union(int i,int j){
    
    
        int parenti = find(i);
        int parentj = find(j);
        
        if(rank[i]<rank[j]){
    
    
            element[parenti]=parentj;
        }
        else if(rank[i]>rank[j]){
    
       
            element[parentj]=parenti;
        }
        else{
    
    
            element[parentj]=parenti;
            rank[parenti]++;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44495738/article/details/112460741
今日推荐