[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 }

 

转载于:https://www.cnblogs.com/yinger33/p/10943505.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值