给你一个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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
加强理解加强理解加强理解