[Leetcode] Minimum Height Trees
2016-05-13 15:20
357 查看
Minimum Height Trees
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.如题,找出最小深度树。一开始没看清题,把问题想复杂了。注意第一句话:
For a undirected graph with tree characteristics,
输入的是具有树特性的无向图,所以肯定是无环图。返回值是根节点列表。
思路:
要使得生成树的深度最小,根节点应当选择内部点,而且应当是整个图的中心。问题是这样的中心点怎么找?这样的中心点又有多少个?题目有给提示:How many MHTs can a graph have at most? 。说实话,看到这样的提示,我并没有什么感觉…不妨先从中心点在哪里入手。中心点应该在图的longest path上。直观上还是很好理解的,根节点就应该取在最长路径的中心上。至于数学上,暂时还没想到要如何证明。想通了这一点,中心点的数目就不难想了:中心点有1个或者2个,若最长路的节点数为奇数,中心点有一个;若为偶数,中心点有两个。第一个思路,找出longest path。任选一个节点进行搜索(广搜深搜均可),然后找出最深的路径 path1。容易证明,path1一定包含在longest_paht中,其长度小于等于最长路。如果从paht1的一个端点出发再搜索一次,就可以找到longest_paht了。所以这个方法需要two pass search。
另一个思路。容易想象,边缘的节点(也即度数为1的节点)不应当为root。所以,通过“层层剥”的方法最终一定可以找到中心点。这个思路的关键是发现中心点数不大于2,但是这一个思路很难发现这一点。有了这个约束条件,这个思路实现起来比前一个方便,而且这个算法的性能应该说比前一个好。
实现
class Solution(object): def findMinHeightTrees(self, n, edges): """ :type n: int :type edges: List[List[int]] :rtype: List[int] """ # Adjacency list adj = [set() for i in xrange(n)] # Degree list degree = [0 for i in xrange(n)] for i, j in edges: adj[i].add(j) adj[j].add(i) for i in xrange(n): degree[i] = len(adj[i]) # Remove nodes level by level (the nodes' degree equal to 1 should be removed) remain = set([i for i in xrange(n)]) while len(remain) > 2: rm_record = [] for v in remain: if degree[v] == 1: # Record nodes that should be removed rm_record.append(v) for v in rm_record: for u in adj[v]: degree[u] -= 1 remain.remove(v) return list(remain) if __name__ == '__main__': s = Solution() print s.findMinHeightTrees(6, [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]])
相关文章推荐
- leetcode 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- leetcode----Longest Substring Without Repeating Characters
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解
- LeetCode[Day 2] Median of Two Sorted Arrays 题解
- LeetCode[Day 3] Longest Substring Without... 题解
- LeetCode [Day 4] Add Two Numbers 题解