最低成本连通所有城市
难度:
标签:
题目描述
代码结果
运行时间: 68 ms, 内存: 20.5 MB
/*
* 思路:
* 1. 使用Kruskal算法来找到最小生成树(Minimum Spanning Tree, MST),从而找到连通所有城市的最低成本。
* 2. 首先将所有的边按照权重进行排序。
* 3. 使用并查集(Union-Find)来检测是否会形成环,并构建最小生成树。
* 4. 使用Java Stream API来处理集合和数组操作。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
class Edge implements Comparable<Edge> {
int city1, city2, cost;
public Edge(int city1, int city2, int cost) {
this.city1 = city1;
this.city2 = city2;
this.cost = cost;
}
public int compareTo(Edge other) {
return this.cost - other.cost;
}
}
public int minimumCost(int n, int[][] connections) {
List<Edge> edges = Arrays.stream(connections)
.map(conn -> new Edge(conn[0] - 1, conn[1] - 1, conn[2]))
.sorted()
.collect(Collectors.toList());
UnionFind uf = new UnionFind(n);
int totalCost = edges.stream()
.filter(edge -> uf.union(edge.city1, edge.city2))
.mapToInt(edge -> edge.cost)
.sum();
return uf.getCount() == n - 1 ? totalCost : -1;
}
class UnionFind {
private int[] parent, rank;
private int count;
public UnionFind(int size) {
parent = new int[size];
rank = new int[size];
count = 0;
for (int i = 0; i < size; i++) {
parent[i] = i;
rank[i] = 1;
}
}
public int find(int p) {
if (parent[p] != p) {
parent[p] = find(parent[p]);
}
return parent[p];
}
public boolean union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) return false;
if (rank[rootP] > rank[rootQ]) {
parent[rootQ] = rootP;
} else if (rank[rootP] < rank[rootQ]) {
parent[rootP] = rootQ;
} else {
parent[rootQ] = rootP;
rank[rootP]++;
}
count++;
return true;
}
public int getCount() {
return count;
}
}
}
解释
方法:
此题解采用了最小生成树(Kruskal算法)的策略来连接所有城市,要求最小的成本。首先,判断边的数量是否少于n-1,若是,则直接返回-1,因为不可能连接所有城市。使用并查集来维护和查询城市间的连通性。城市和其连接边按照连接成本从低到高排序。遍历排序后的边,使用并查集的find函数来查找每条边两个城市的根节点,如果根节点不同,则使用unite函数合并这两个根节点,并累加当前边的成本到总成本中。当选取的边数达到n-1时,所有城市已经连通,返回累计的最小成本。如果循环结束后,选取的边数仍然少于n-1,则返回-1表示不能连通所有城市。
时间复杂度:
O(m log m)
空间复杂度:
O(n + m)
代码细节讲解
🦆
在并查集中,路径压缩的主要目的是什么,它如何帮助提高查找根节点的效率?
▷🦆
为什么在选择边时,必须先对边按照成本从低到高进行排序?这种排序对算法的最终结果有什么影响?
▷🦆
如果在处理过程中,两个城市的根节点相同,为什么不需要合并这两个节点?这种情况会对算法的运行结果产生什么影响?
▷🦆
你提到了如果边的数量少于n-1则无法连通所有城市,这个结论是怎么得出的?是否有数学或逻辑上的支持?
▷