zoukankan      html  css  js  c++  java
  • 并查集

    /*
    * 将多个集合合并成没有交集的集合。
     给定一个字符串的集合,格式如:{aaa,bbb,ccc},{bbb,ddd},{eee,fff},{ggg},{ddd,hhh}要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,
     例如上例应输出{aaabbbcccdddhhh},{eeefff},{ggg}。
    (1)请描述你解决这个问题的思路;
    (2)请给出主要的处理流程,算法,以及算法的复杂度;
    (3)请描述可能的改进。
     
     解:
     1.对字符集合进行依次编号,分别为[0,1,2,3,4]。如果将{{aaa,bbb,ccc},{bbb,ddd},{eee,fff},{ggg},{ddd,hhh}}看做成二维数组,编号对应二维数组的下标。
        初始化一个数组int father[] = {0,1,2,3,4};,代表其下标。
        将字符串集合放到list<Set<String>>中集合resList
     2.创建一个Map<String,List<Integer>>,key为字符串,value为字符串所在的编号。遍历集合找出每个字符串的编号,如下:
        aaa 0
        bbb 0,1
        ccc 0
        ddd 1,4
        eee 2
        fff 2
        ggg 3
        hhh 4
     3.合并,合并的时候将编号大的集合合并到小的集合里面。方法是:遍历map中的List<Integer>,更新father对应的下表,如下:
        aaa 0       {0,1,2,3,4}
        bbb 0 1     {0,0,2,3,4}
        ccc 0       {0,0,2,3,4}
        ddd 1 4     {0,0,2,3,0}
        eee 2       {0,0,2,3,0}
        fff 2       {0,0,2,3,0}
        ggg 3       {0,0,2,3,0}
        hhh 4       {0,0,2,3,0}
        之后遍历father数组,如果i!=faterh[i],则
            Set<String> dest = resList.get(father[i]);
            Set<String> sour = resList.get(i);
            sour.addAll(dest);
    */
    import java.util.List;
    import java.util.ArrayList;
    import java.util.Set;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Arrays;
    public class ShowDisjointSet{
    
        private List<Set<String>> resList = new ArrayList<Set<String>>();
        private int[] father;
        private int len;
    
        public static void main(String args[]){
            String[] str0 = {"aaa","bbb","ccc"};
            String[] str1 = {"bbb","ddd"};
            String[] str2 = {"eee","fff"};
            String[] str3 = {"ggg"};
            String[] str4 = {"ddd","hhh"};
            String[][] arr = {str0,str1,str2,str3,str4};
            
            ShowDisjointSet obj = new ShowDisjointSet();
            obj.getResList(arr);
    
        }
    
        // 1:并查集
        public void getResList(String[][] arr){
            len = arr.length;
            // 初始化resList
            for(String[] tmp:arr){
                Set<String> set = new HashSet<String>();
                set.addAll(Arrays.asList(tmp));
                resList.add(set);
            }
            // 初始化数组
            father = new int[len];
            for(int i=0;i<len;i++){
                father[i] = i;
            }
            Map<String,List<Integer>> map = getRes(arr);
            unionSet(map);
            System.out.println(resList);
        }
    
        // 2:遍历集合
        public Map<String,List<Integer>> getRes(String[][] arr){
            Map<String,List<Integer>> map = new HashMap<String,List<Integer>>();
            for(int i=0; i<len; i++){
                for(String tmp:arr[i]){
                    if(!map.containsKey(tmp)){
                        List<Integer> list = new ArrayList<Integer>();
                        list.add(i);
                        map.put(tmp,list);
                    }else{
                        map.get(tmp).add(i);
                    }
                }
            }
            return map;
        }
    
        // 3:合并集合
        public void unionSet(Map<String,List<Integer>> map){
            Iterator<Map.Entry<String,List<Integer>>> ite = map.entrySet().iterator();
            while(ite.hasNext()){
                Map.Entry<String,List<Integer>> entry = ite.next();
                String key = entry.getKey();
                List<Integer> value = entry.getValue();
                unionHelp(value);
                System.out.println(key+":"+value);
            }
    
            System.out.println("the father array is "+ Arrays.toString(father));
    
            for(int i=0; i<len; i++){
                if(i != father[i]){
                    Set<String> dest = resList.get(father[i]);
                    Set<String> sour = resList.get(i);
                    dest.addAll(sour);
                }
            }
    
            for(int i=0; i<len; i++){
                if(i != father[i]){
                    resList.get(i).clear();
                }
            }
    
        }
    
        public void unionHelp(List<Integer> list){
            int min = getFather(list.get(0));
            int size = list.size();
            for(int i=0; i<size; i++){
                father[list.get(i)] = min;
            }
        }
        
        public int getFather(int index){
            while(index!=father[index]){
                index = father[index];
            }
            return index;
        }
    
    }
  • 相关阅读:
    python 三方面库整理
    windows MYSQL 安装及修改root密码
    TCP 套叠字
    自动化谷歌浏览驱动
    python os
    python 协程
    python GIL :全局解释器
    python 多进程
    python 多线程
    python 3 往Excel 中的写入内容但不覆盖原内容
  • 原文地址:https://www.cnblogs.com/ningvsban/p/4079266.html
Copyright © 2011-2022 走看看