LeetCode—每日一题:交换字符串中的元素(并查集)

交换字符串中的元素(中等)

题目来源:力扣

LeetCode—每日一题:交换字符串中的元素(并查集)_第1张图片
LeetCode—每日一题:交换字符串中的元素(并查集)_第2张图片

解题

使用并查集,参考自题解
在原题解上加了注释,删除了size的hashmap

class Solution {
     
    public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
     
        if(pairs.size() == 0){
     
            return s;
        }
        UnionFind uf = new UnionFind(s.length());
        for(List<Integer> pair : pairs){
     
            // 根据题意合并
            uf.union(pair.get(0),pair.get(1));
        }

        Map<Integer,PriorityQueue<Character>> map = new HashMap<>();
        for(int i = 0; i < s.length(); i++){
     
            int root = uf.find(i);
            // 区分父节点写入不同的优先队列,优先队列默认会从小到大排
            if(map.containsKey(root)){
     
                map.get(root).offer(s.charAt(i));
            }else {
     
                PriorityQueue<Character> minHeap = new PriorityQueue<>();
                minHeap.offer(s.charAt(i));
                map.put(root,minHeap);
            }
        } 

        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < s.length(); i++){
     
            int root = uf.find(i);
            // 区分头节点的拿出来,就会是有序的
            sb.append(map.get(root).poll());
        }
        return sb.toString();  
    }
    //并查集的类
    class UnionFind{
     
        public Map<Integer,Integer> map;    //用来记录key:当前节点 value:父节点
        public UnionFind(int n){
         //构造函数
            map = new HashMap<>();
            // 构造并查集,初始化两个map
            for(int i = 0; i < n; i++){
     
                map.put(i,i);   // 当前节点就是自己的父节点
            }
        }

        // 找到节点的头节点
        public int find(int i){
     
            int root = map.get(i);  //找到父节点
            if(i != root){
       //用父节点去比对当前值,不相等则说明还没找到父节点
                root = find(root);  //递归找父节点
            }
            map.put(i,root);    //扁平化处理,让这个节点能直接指向头节点
            return root;
        }

        public void union(int p,int q){
      // 联合两个节点
            int pRoot = find(p);    // 拿出父节点
            int qRoot = find(q);    
            if(pRoot != qRoot){
      // 父节点肯定是不同的才需要合并
                map.put(pRoot,qRoot);
            }
        }
    }
}

LeetCode—每日一题:交换字符串中的元素(并查集)_第3张图片

你可能感兴趣的:(LeetCode)