0kruskal+并查集 LeetCode1584. 连接所有点的最小费用

分析

最小生成树的问题
kruskal : 每次加入最短的边,且边加入后不会构成环。
并查集:判断加入的边的两点是否会构成回环
edge数据结构:将边,两个端点整合起来

解法一:kruskal+并查集

class Solution {
    public int minCostConnectPoints(int[][] points) {

    int n = points.length;
        List<edge> list = new ArrayList<>();
        Parent parent = new Parent(n);
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int dis = Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]);
                list.add(new edge(i,j,dis));
            }
        }
        Collections.sort(list,(a,b)->(a.distance-b.distance));
        int ans = 0;
        for (edge e : list) {
            if (!parent.isConnect(e.start,e.end)) {
                parent.union(e.start,e.end);
                ans += e.distance;
            }
        }
        return ans;
    }

    class edge{
        int start;
        int end;
        int distance;
        edge(int a, int b, int c) {
            start = a;
            end = b;
            distance = c;
        }
    }

    class Parent {
        int[] parent;
        Parent (int n) {
            parent = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
            }
        }

        public int find(int x) {
            if (x != parent[x]) {
                x = find(parent[x]);
            }
            return parent[x];
        }

        public void union(int i, int j){
            int a = find(i);
            int b = find(j);
            parent[a] = b;
        }

        public boolean isConnect(int i, int j) {
            int a = find(i);
            int b = find(j);
            return a == b;
        }
    }
}

20240307第二次做

class Solution {
    public int minCostConnectPoints(int[][] points) {
        int n = points.length;
        int[][] dis = new int[n*(n-1)/2][3];
        int index = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int distance = Math.abs(points[i][0]-points[j][0]) + Math.abs(points[i][1]-points[j][1]);
                dis[index][0] = i;
                dis[index][1] = j;
                dis[index++][2] = distance;
            }
        }

        Arrays.sort(dis, new Comparator<int[]>(){
            public int compare(int[] a, int[] b) {
                // return a[2] > b[2] ? 1 : -1;
                if (a[2] == b[2]) {
                    return 0;
                }
                return a[2] > b[2] ? 1 : -1;
            }
        });

        int ans = 0, count = 0;
        int[] parent = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
        for (int[] di : dis) {
            if (find(parent, di[0]) != find(parent, di[1])) {
                count++;
                ans += di[2];
                parent[find(parent, di[0])] = find(parent, di[1]);
            }
            if (count == n - 1) {
                break;
            }
        }

        return ans;
    }

    public int find(int[] parent, int i) {
        if (parent[i] != i) {
            parent[i] = find(parent, parent[i]);
        }
        return parent[i];
    }
}

prim算法

class Solution {
    public int minCostConnectPoints(int[][] points) {
        int ans = 0;
        int n = points.length;
        int[][] adjoin = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {
                    adjoin[i][j] = Integer.MAX_VALUE;
                }
                adjoin[i][j] = Math.abs(points[i][0]-points[j][0]) + Math.abs(points[i][1]-points[j][1]);
            }
        }
        boolean[] visited = new boolean[n];
        visited[0] = true;
        int[] dis = new int[n];
        for (int i = 0; i < n; i++) {
            dis[i] = adjoin[0][i];
        }
        for (int i = 1; i < n; i++) {
            int min = Integer.MAX_VALUE;
            int next = 0;
            for (int j = 0; j < n; j++) {
                if (!visited[j] && dis[j] < min) {
                    min = dis[j];
                    next = j;
                }
            }
            ans += min;
            visited[next] = true;
            for (int j = 0; j < n; j++) {
                if (!visited[j] && adjoin[next][j] < dis[j]) {
                    dis[j] = adjoin[next][j];
                }
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值