Given a list of Connections, which is the Connection class (the city name at both ends of the edge and a cost between them), find edges that can connect all the cities and spend the least amount.
Return the connects if can connect all the cities, otherwise return empty list.
Example
Example 1:
Input:
["Acity","Bcity",1]
["Acity","Ccity",2]
["Bcity","Ccity",3]
Output:
["Acity","Bcity",1]
["Acity","Ccity",2]
Example 2:
Input:
["Acity","Bcity",2]
["Bcity","Dcity",5]
["Acity","Dcity",4]
["Ccity","Ecity",1]
Output:
[]
Explanation:
No way
Notice
Return the connections sorted by the cost, or sorted city1 name if their cost is same, or sorted city2 if their city1 name is also same.
思路:// return empty list好做,判断union find之后的边,是否是n-1
// 如何用最小的边去连接,方法就是:首先对connect按照value和city进行排序
// 然后把最小边的node,也就是对应的number取出来,判断是否相连,不相连,连起来,这样一定是先用最小的边把整个图连接起来,
// 如果全部连起来了,那么后面进来的connection会因为前面已经连起来了,那么不会再连了,因为后面的都是边值比较大的点;所以所求就是最小的cost;
/**
* Definition for a Connection.
* public class Connection {
* public String city1, city2;
* public int cost;
* public Connection(String city1, String city2, int cost) {
* this.city1 = city1;
* this.city2 = city2;
* this.cost = cost;
* }
* }
*/
public class Solution {
/**
* @param connections given a list of connections include two cities and cost
* @return a list of connections from results
*/
private class UnionFind {
private int[] father;
private int count;
public UnionFind(int n) {
this.father = new int[n + 1];
for(int i = 0; i <= n; i++) {
father[i] = i;
}
this.count = n;
}
public int find(int x) {
int j = x;
while(father[j] != j) {
j = father[j];
}
// path compression;
while(x != j) {
int fx = father[x];
father[x] = j;
x = fx;
}
return j;
}
public void union(int a, int b) {
int root_a = find(a);
int root_b = find(b);
if(root_a != root_b) {
father[root_a] = root_b;
this.count--;
}
}
public int getCount() {
return this.count;
}
}
private class ConnectionComparator implements Comparator<Connection> {
@Override
public int compare(Connection a, Connection b) {
if(a.cost != b.cost) {
return a.cost - b.cost;
} else {
if(!a.city1.equals(b.city1)) {
return a.city1.compareTo(b.city1);
} else {
return a.city2.compareTo(b.city2);
}
}
}
}
public List<Connection> lowestCost(List<Connection> connections) {
Collections.sort(connections, new ConnectionComparator());
HashMap<String, Integer> cityMap = new HashMap<>();
int count = 0;
for(Connection connection: connections) {
String city1 = connection.city1;
if(!cityMap.containsKey(city1)) {
cityMap.put(city1, count++);
}
String city2 = connection.city2;
if(!cityMap.containsKey(city2)) {
cityMap.put(city2, count++);
}
}
UnionFind uf = new UnionFind(count);
List<Connection> list = new ArrayList<>();
for(Connection connection: connections) {
int a = cityMap.get(connection.city1);
int b = cityMap.get(connection.city2);
if(uf.find(a) != uf.find(b)) {
uf.union(a, b);
list.add(connection);
}
}
return uf.getCount() == 1 ? list : new ArrayList<>();
}
}