0
点赞
收藏
分享

微信扫一扫

算法基础进阶部分-并查集

殇感故事 2022-04-05 阅读 58
java算法
/**
 * 并查集
 */
public class BingChaJi {

    //岛
    public static int countIslands(int[][] m) {
        //如果二维数组二维为空返回
        if (m == null || m[0] == null) {
            return 0;
        }
        //N为二维数组的行数
        int N = m.length;
        //M为二维数组的列数
        int M = m[0].length;
        int res = 0;
        //外层循环行
        for (int i = 0; i < N; i++) {
//            内层循环列
            for (int j = 0; j < M; j++) {
                //在从上往下循环列的时候碰到了1就进行感染操作
                if (m[i][j] == 1) {
                    //记录岛的数量
                    res++;
//                    感染操作
                    infect(m, i, j, N, M);
                }
            }
        }
        return res;
    }

    private static void infect(int[][] m, int i, int j, int N, int M) {
        //如果当前的坐标越界了或者不为1那么就返回
        if (i < 0 || i >= N || j < 0 || j >= M || m[i][j] != 1) {
            return;
        }
        //i,j没越界,并且当前位置值是1 就直接把当前的1感染成2
        m[i][j] = 2;
        //下边进行感染操作
        infect(m, i + 1, j, N, M);
//        上边进行感染操作
        infect(m, i - 1, j, N, M);
        //右边进行感染操作
        infect(m, i, j + 1, N, M);
        //左边进行感染操作
        infect(m, i, j - 1, N, M);

    }

    //并查集
    public static class Element<V> {
        public V value;

        public Element(V value) {
            this.value = value;
        }
    }

    public static class UnionFindSet<V> {
        public HashMap<V, Element> elementMap;
        //key 某个元素 value 该元素的父
        public HashMap<Element<V>, Element<V>> fatherMap;
        //key 某个集合的代表元素,value 该集合的大小
        public HashMap<Element<V>, Integer> sizeMap;

        public UnionFindSet(List<V> list) {
            elementMap = new HashMap<>();
            fatherMap = new HashMap<>();
            sizeMap = new HashMap<>();
            for (V value : list) {
                Element<V> element = new Element<V>(value);
                elementMap.put(value, element);
                fatherMap.put(element, element);
                sizeMap.put(element, 1);
            }
        }

        //给定应该ele,往上一直找,把代表元素返回
        private Element<V> findHead(Element<V> element) {
            Stack<Element<V>> path = new Stack<>();
            while (element != fatherMap.get(element)) {
                path.push(element);
                element = fatherMap.get(element);
            }
            while (!path.isEmpty()) {
                fatherMap.put(path.pop(), element);
            }
            return element;
        }

        public boolean isSameSet(V a, V b) {
            if (elementMap.containsKey(a) && elementMap.containsKey(b)) {
                return findHead(elementMap.get(a)) == findHead(elementMap.get(b));
            }
            return false;
        }

        public void union(V a, V b) {
            if (elementMap.containsKey(a) && elementMap.containsKey(b)) {
                Element<V> aF = findHead(elementMap.get(a));
                Element<V> bF = findHead(elementMap.get(b));
                if (aF != bF) {
                    Element<V> big = sizeMap.get(aF) >= sizeMap.get(bF) ? aF : bF;
                    Element<V> small = big == aF ? bF : aF;
                    fatherMap.put(small, big);
                    sizeMap.put(big, sizeMap.get(aF) + sizeMap.get(bF));
                    sizeMap.remove(small);
                }
            }
        }

        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(3);
            list.add(4);
            list.add(5);
            list.add(6);
            UnionFindSet<Integer> set = new UnionFindSet(list);

            set.union(1, 2);
            boolean sameSet = set.isSameSet(1, 2);
            System.out.println(sameSet);


        }
    }

    public static void main(String[] args) {
        int[][] arr =
                {{0, 0, 0, 0, 0, 0, 0},
                        {0, 1, 1, 0, 0, 0, 0},
                        {0, 1, 0, 0, 0, 0, 0},
                        {0, 0, 0, 1, 1, 1, 1},
                        {0, 0, 0, 1, 0, 0, 1},
                        {0, 0, 0, 0, 0, 0, 0},
                        {0, 1, 1, 1, 0, 0, 0}};
        System.out.println("感染前数组的样子:");
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[0].length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
        int i1 = countIslands(arr);
        System.out.println("岛的个数是:" + i1);
        System.out.println("感染后的数组的样子:");
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[0].length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }


}
举报

相关推荐

0 条评论