package com.heu.wsq.leetcode.bingchaji;
import java.util.*;
/**
* 1584. 连接所有点的最小费用
* @author wsq
* @date 2021/1/19
* 给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。
* 连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。
* 请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。
* 示例 1:
*
* 输入:points = [[3,12],[-2,5],[-4,1]]
* 输出:18
*
* 链接:https://leetcode-cn.com/problems/min-cost-to-connect-all-points
*/
public class MinCostConnectPoints {
/**
* 1.计算各个点之间的边长
* 2.排序边长集合,从小到大遍历边长
* 3.利用并查集判断两点是否连通,若已经连通,则忽略当前边
* @param points
* @return
*/
public int minCostConnectPoints(int[][] points){
int n = points.length;
UnionFind unionFind = new UnionFind(n);
// 计算两点之间的边的距离
List<Edge> list = new ArrayList<>();
for (int i = 0; i < n; i++){
for (int j = i + 1; j < n; j++){
list.add(new Edge(dist(points, i, j), i, j));
}
}
// 按照边长从小到大排序边
Collections.sort(list, new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return o1.len - o2.len;
}
});
// 统计总长度
int ret = 0, num = 1;
for (Edge edge : list) {
int len = edge.len, x = edge.x, y = edge.y;
if (!unionFind.isConnected(x, y)){
unionFind.union(x, y);
ret += len;
num++;
if (num == n){
break;
}
}
}
return ret;
}
private int dist(int[][] points, int i, int j) {
return Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]);
}
private class UnionFind{
private int[] parent;
private int[] rank;
private int n;
public UnionFind(int n){
this.n = n;
this.rank = new int[n];
this.parent = new int[n];
Arrays.fill(rank, 1);
for (int i = 0; i < n; i++) {
this.parent[i] = i;
}
}
public int find(int x){
if (x != parent[x]){
parent[x] = find(parent[x]);
}
return parent[x];
}
public void union(int x, int y){
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY){
return;
}
if (rank[rootX] < rank[rootY]){
int tmp = rootX;
rootX = rootY;
rootY = tmp;
}
rank[rootX] += rank[rootY];
parent[rootY] = parent[rootX];
}
public boolean isConnected(int x, int y){
return find(x) == find(y);
}
}
}
class Edge{
int x;
int y;
int len;
public Edge(int len, int x, int y){
this.x = x;
this.y = y;
this.len = len;
}
}
1584. 连接所有点的最小费用(并查集)
最新推荐文章于 2023-09-16 22:13:25 发布
本文介绍了一种解决LeetCode上‘连接所有点的最小费用’问题的算法实现。该问题要求计算2D平面上多个点间连接的最小总费用,采用曼哈顿距离作为两点间的成本。文章详细阐述了使用并查集结合贪心策略来寻找最优解的方法。
813

被折叠的 条评论
为什么被折叠?



