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

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。
连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。
请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

看大佬们说并查集不会就别想过年了,所以哦它来了它来了(狗头保命)。

参考大佬题解
上代码,脑袋乱看了好几种解法。
看的大佬的是比较简单的。

// 定义边
class Edge {
    // 分别表示一条边两个点的索引和边长
    int a, b, val;
    public Edge(int a, int b, int val) {
        this.a = a;
        this.b = b;
        this.val = val;
    }
}

class Solution {
    // 并查集集合
    List<Integer> p;
    public int minCostConnectPoints(int[][] points) {
        p = new ArrayList<>();
        int n = points.length;
        // 初始化并查集
        for(int i = 0; i < n; i++) {
            p.add(i);
        }
        // 添加所有可能的边到列表中
        List<Edge> edges = new ArrayList<>();
        for(int i = 0; i < n - 1; i++) {
            for(int j = i + 1; j < n; j++) {
                // 添加第i个点和第j个点组成的边
                edges.add(new Edge(i, j, Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1])));
            }
        }
        // 进行一个升序排序,为了优先选取短的边
        Collections.sort(edges, (a, b) -> a.val - b.val);

        // 从低到高遍历所有边
        int res = 0;
        for(Edge e : edges) {
            // 查找这条边两个端点所处的集合根元素
            int a = find(e.a), b = find(e.b);
            // 如果这两条边不是一个集合的,那么就添加这条边
            if(a != b) {
                // 并且将这两个点所在的集合根元素加入一个集合
                p.set(a, b);
                // 答案中添加这条边长度
                res += e.val;
            }
        }

        return res;
    }

    // 并查集模板方法,用于查找根元素
    public int find(int x) {
        if(p.get(x) != x) {
            p.set(x, find(p.get(x)));
        }

        return p.get(x);
    }
}

作者:lippon
链接:https://leetcode-cn.com/problems/min-cost-to-connect-all-points/solution/java-kruskalsuan-fa-bing-cha-ji-by-lippo-8g8r/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

其中,还是需要了解java ArrrayList的set方法

set() 方法用于替换动态数组中指定索引的元素。
set() 方法的语法为:
arraylist.set(int index, E element)
注:arraylist 是 ArrayList 类的一个对象。
参数说明:

  • index - 索引位置
  • element - 将在 index 位置替换进去的新元素

下面再附上一个官方代码

class Solution {
    public int minCostConnectPoints(int[][] points) {
        int n = points.length;
        DisjointSetUnion dsu = new DisjointSetUnion(n);
        List<Edge> edges = new ArrayList<Edge>();
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                edges.add(new Edge(dist(points, i, j), i, j));
            }
        }
        Collections.sort(edges, new Comparator<Edge>() {
            public int compare(Edge edge1, Edge edge2) {
                return edge1.len - edge2.len;
            }
        });
        int ret = 0, num = 1;
        for (Edge edge : edges) {
            int len = edge.len, x = edge.x, y = edge.y;
            if (dsu.unionSet(x, y)) {
                ret += len;
                num++;
                if (num == n) {
                    break;
                }
            }
        }
        return ret;
    }

    public int dist(int[][] points, int x, int y) {
        return Math.abs(points[x][0] - points[y][0]) + Math.abs(points[x][1] - points[y][1]);
    }
}

class DisjointSetUnion {
    int[] f;
    int[] rank;
    int n;

    public DisjointSetUnion(int n) {
        this.n = n;
        this.rank = new int[n];
        Arrays.fill(this.rank, 1);
        this.f = new int[n];
        for (int i = 0; i < n; i++) {
            this.f[i] = i;
        }
    }

    public int find(int x) {
        return f[x] == x ? x : (f[x] = find(f[x]));
    }

    public boolean unionSet(int x, int y) {
        int fx = find(x), fy = find(y);
        if (fx == fy) {
            return false;
        }
        if (rank[fx] < rank[fy]) {
            int temp = fx;
            fx = fy;
            fy = temp;
        }
        rank[fx] += rank[fy];
        f[fy] = fx;
        return true;
    }
}

class Edge {
    int len, x, y;

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

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/min-cost-to-connect-all-points/solution/lian-jie-suo-you-dian-de-zui-xiao-fei-yo-kcx7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

加强理解加强理解加强理解

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值