[LeetCode] Minimum Spanning Tree
Posted yinger33
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] Minimum Spanning Tree相关的知识,希望对你有一定的参考价值。
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.
首先学习一下并查集的一些概念:
Disjoint Set: 对于Set里面的Node,只能属于一个Set。
支持两种操作:find(找到这个Node属于哪个Set)和 union(合并两个Set)
树是一种特例:
- Set指的是Root of the tree。这也很好理解,如果Node在一棵树上,那么他们share同一个树的Root。
- 复杂度:find(o(h)) - h means the height of the tree,union(o(1))
Reference:https://www.youtube.com/watch?v=UBY4sF86KEY
对于本道题(谁背谁会题),解法是先按照Cost Sort Connections。然后遍历Connections,查和并。如果两个node不属于一个Set,push到result list里。返回的时候检查一下result和点数目的关系(如果全部联通的话,Edge数应为Node数减1)。
代码如下。可以进一步优化:由于find的复杂度为树的高度,那么并的时候以更高的树的Root为Parent则可以减少find的复杂度。
1 /** 2 * Definition for a Connection. 3 * public class Connection { 4 * public String city1, city2; 5 * public int cost; 6 * public Connection(String city1, String city2, int cost) { 7 * this.city1 = city1; 8 * this.city2 = city2; 9 * this.cost = cost; 10 * } 11 * } 12 */ 13 public class Solution { 14 /** 15 * @param connections given a list of connections include two cities and cost 16 * @return a list of connections from results 17 */ 18 Map<String, String> parents = new HashMap<>(); 19 20 public List<Connection> lowestCost(List<Connection> connections) { 21 Collections.sort(connections, new MyComparator()); 22 23 List<Connection> res = new ArrayList<>(); 24 Set<String> nodes = new HashSet<>(); 25 26 for (Connection c : connections) { 27 nodes.add(c.city1); 28 nodes.add(c.city2); 29 30 String s1 = find(c.city1); 31 String s2 = find(c.city2); 32 33 if (!s1.equals(s2)) { 34 union(s1, s2); 35 res.add(c); 36 } 37 } 38 39 if (nodes.size() != (res.size() + 1)) { 40 return new ArrayList<Connection>(); 41 } 42 43 return res; 44 } 45 46 private String find(String x) { 47 String curr = x; 48 49 while (parents.get(curr) != null) { 50 curr = parents.get(curr); 51 } 52 53 return curr; 54 } 55 56 private void union(String s1, String s2) { 57 parents.put(s1, s2); 58 } 59 60 class MyComparator implements Comparator<Connection> { 61 @Override 62 public int compare(Connection a, Connection b) { 63 if (a.cost != b.cost) { 64 return a.cost - b.cost; 65 } 66 67 if (!a.city1.equals(b.city1)) { 68 return a.city1.compareTo(b.city1); 69 } 70 71 return a.city2.compareTo(b.city2); 72 } 73 } 74 }
以上是关于[LeetCode] Minimum Spanning Tree的主要内容,如果未能解决你的问题,请参考以下文章
leetcode@ [310] Minimum Height Trees
LeetCode 2187. Minimum Time to Complete Trips