其他分享
首页 > 其他分享> > LeetCode 每日一题1584. 连接所有点的最小费用

LeetCode 每日一题1584. 连接所有点的最小费用

作者:互联网

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

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi]

连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。

请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

示例 1:
在这里插入图片描述

输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
输出:20
解释:
我们可以按照上图所示连接所有点得到最小总费用,总费用为 20 。
注意到任意两个点之间只有唯一一条路径互相到达。

在这里插入图片描述

示例 2:

输入:points = [[3,12],[-2,5],[-4,1]]
输出:18

示例 3:

输入:points = [[0,0],[1,1],[1,0],[-1,1]]
输出:4

示例 4:

输入:points = [[-1000000,-1000000],[1000000,1000000]]
输出:4000000

示例 5:

输入:points = [[0,0]]
输出:0

提示:

方法一:Kruskal + 并查集

「鲁斯卡尔算法」:是求连通网的最小生成树的一种方法。对应本题的最小费用。
「并查集」:本题维护点与点的连通性。

解题思路

参考代码

public int minCostConnectPoints(int[][] points) {
    int n = points.length;
    // 生成所有边并排序
    List<Edge> edges = new ArrayList<>();
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            edges.add(new Edge(i, j, Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1])));
        }
    }
    edges.sort(Comparator.comparingInt(e -> e.len));

    // 加入并查集,union成功就把这条加入结果
    UnionFind unionFind = new UnionFind(n);
    int ret = 0, count = 1;
    for (Edge edge : edges) {
        if (unionFind.union(edge.x, edge.y)) {
            ret += edge.len;
            count++;
        }
        if(count == n) {
            break;
        }
    }
    return ret;
}

class UnionFind {
    private int[] parent;
    public UnionFind(int n) {
        parent = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
        }
    }
    public boolean union(int x, int y) {
        int rootX = find(x), rootY = find(y);
        if (rootX == rootY) {
            return false;
        }
        parent[rootX] = rootY;
        return true;
    }
    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
}

class Edge {
    private int x;
    private int y;
    private int len;
    public Edge (int x, int y, int len) {
        this.x = x;
        this.y = y;
        this.len = len;
    }
}

执行结果
在这里插入图片描述

标签:parent,示例,int,查集,1584,points,len,一题,LeetCode
来源: https://blog.csdn.net/qq_27007509/article/details/112802202