力扣labuladong一刷day47天并查集

力扣labuladong一刷day47天并查集

一、261. 以图判树

题目链接:https://leetcode.cn/problems/graph-valid-tree/
思路:本题的要求是给你一组连接边,判断是否能组成树,其实只要是无环图,就是数,那问题也就变成了是否能组成无环图。其实只要新加的这两条边对应的节点,如果原本就在同一个联通分量中,再给连上边即为环,如果这条边没加入之前两节点不属于同一联通分量,就不会成环。对于是否在同一个联通分量内这种事情是Union-Find 算法的拿手绝活。

class Solution {
   
    public boolean validTree(int n, int[][] edges) {
   
        UF uf = new UF(n);
        for (int[] edge : edges) {
   
            if (uf.connected(edge[0], edge[1])){
   
                return false;
            }
            uf.union(edge[0], edge[1]);
        }
        return uf.count == 1;
    }

    class UF {
   
        int[] parent;
        int count;

        public UF(int n) {
   
            parent = new int[n];
            for (int i = 0; i < n; i++) {
   
                parent[i] = i;
            }
            count = n;
        }

        int find(int x) {
   
            if (x != parent[x]) {
   
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
        boolean connected(int x, int y) {
   
            return find(x) == find(y);
        }

        void union(int x, int y) {
   
            int a = find(x);
            int b = find(y);
            if (a == b) return;
            parent[a] = b;
            count--;
        }

        int count() {
   
            return count;
        }
    }
}

二、1135. 最低成本联通所有城市

题目链接:https://leetcode.cn/problems/connecting-cities-with-minimum-cost/
思路:本题边带权重,求的是最小生成树,构造树在上一题中已经介绍,本题只需要考虑如果最小,采用贪心的思路,可以把所有的边按照从小到大进行排序,逐个判断是否在同一联通分量,不在然后加入,最后如果联通分量为1则为最小生成树。

class Solution {
   
    public int minimumCost(int n, int[][] connections) {
   
        Arrays.sort(connections, (a, b) -> (a[2] - b[2]));
        int cost = 0;
        UF uf = new UF(n);
        for (int[] ints : connections) {
   
            if (!uf.connected(ints[0], ints[1])) {
   
                uf.union(ints[0], ints[1]);
                cost += ints[2];
            }
        }
        if (uf.getCount() != 1) return -1;
        return cost;
    }

    class UF{
   
        int[] parent;
        int count;
        public UF(int n) {
   
            parent = new int[n+1];
            for (int i = 0; i <= n; i++) {
   
                parent[i] = i;
            }
            count = n;
        }
        int find(int x) {
   
            if (x != parent[x]) {
   
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
        boolean connected(int x, int y) {
   
            return find(x) == find(y);
        }
        void union(int x, int y) {
   
            int a = find(x);
            int b = find(y);
            if (a == b) return;
            parent[a] = b;
            count--;
        }
        int getCount() {
   
            return count;
        }
    }
}

三、1584. 连接所有点的最小费用

题目链接:https://leetcode.cn/problems/min-cost-to-connect-all-points/
思路:求连接所有节点的最小费用也就是求最小生成树,本题只给出了所有的点,和权重的计算方法,但是没有给边,需要我们去计算出所有的边,以及对应的权重,之后就可以使用并查集算法来进行处理,还是和上一题一样,只要需要加入的这条边的两个节点,之前不在联通,就可以加,否则加了就成环。

class Solution {
   
   public int minCostConnectPoints(int[][] points) {
   
        int n = points.length;
        List<int[]> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
   
            for (int j = i+1; j < n; j++) {
   
                int xi = points[i][0], yi = points[i][1];
                int xj = points[j][0], yj = points[j][1];
                list.add(new int[]{
   i, j, Math.abs(xi - xj) + Math.abs(yi- yj)});
            }
        }
        Collections.sort(list, (a, b) -> {
   
            return a[2] - b[2];
        });
        UF uf = new UF(n);
        int cost = 0;
        for (int[] ints : list) {
   
            if (!uf.connected(ints[0], ints[1])) {
   
                uf.union(ints[0], ints[1]);
                cost += ints[2];
            }
        }
        return cost;
    }
    class UF{
   
        int[] parent;
        int count;
        public UF(int n) {
   
            parent = new int[n];
            for (int i = 0; i < n; i++) {
   
                parent[i] = i;
            }
            count = n;
        }
        int find(int x) {
   
            if (x != parent[x]) {
   
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
        boolean connected(int x, int y) {
   
            return find(x) == find(y);
        }
        void union(int x, int y) {
   
            int a = find(x);
            int b = find(y);
            if (a == b) return;
            parent[a] = b;
            count--;
        }
        int getCount() {
   
            return count;
        }
    }
}

相关推荐

  1. labuladongday47

    2023-12-26 20:26:03       61 阅读
  2. labuladongday46

    2023-12-26 20:26:03       57 阅读
  3. labuladongday42图的遍历

    2023-12-26 20:26:03       53 阅读
  4. labuladongday45二分图判定

    2023-12-26 20:26:03       65 阅读
  5. labuladongday35

    2023-12-26 20:26:03       43 阅读
  6. labuladongday34

    2023-12-26 20:26:03       58 阅读
  7. labuladongday36

    2023-12-26 20:26:03       71 阅读
  8. labuladongday52LRU算法

    2023-12-26 20:26:03       59 阅读
  9. labuladongday53LFU 算法

    2023-12-26 20:26:03       60 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-26 20:26:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-26 20:26:03       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-26 20:26:03       82 阅读
  4. Python语言-面向对象

    2023-12-26 20:26:03       91 阅读

热门阅读

  1. 添加与搜索单词 - 数据结构设计[中等]

    2023-12-26 20:26:03       60 阅读
  2. Oracle動態傳入function

    2023-12-26 20:26:03       64 阅读
  3. uni-app和Vue.js有什么区别?

    2023-12-26 20:26:03       55 阅读
  4. Flutter开发一个Wifi信号测量应用

    2023-12-26 20:26:03       63 阅读
  5. 防御100g的ddos攻击需要花多少钱

    2023-12-26 20:26:03       55 阅读
  6. 掌握这些百度SEO优化技巧

    2023-12-26 20:26:03       49 阅读
  7. Qt判断linux是否存在网卡

    2023-12-26 20:26:03       56 阅读
  8. Ts声明ElementUI控件

    2023-12-26 20:26:03       60 阅读
  9. PTA删除单链表偶数节点(C语言)

    2023-12-26 20:26:03       60 阅读
  10. GBASE南大通用-管理用户定义函数(UDF)

    2023-12-26 20:26:03       56 阅读