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.

Format
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges(each edge is a pair of labels).

You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

Example 1 :

  1. Input: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
  2.  
  3. 0
  4. |
  5. 1
  6. / \
  7. 2 3
  8.  
  9. Output: [1]

Example 2 :

  1. Input: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
  2.  
  3. 0 1 2
  4. \ | /
  5. 3
  6. |
  7. 4
  8. |
  9. 5
  10.  
  11. Output: [3, 4]

Note:

  • According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”
  • The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

Java:

  1. public List<Integer> findMinHeightTrees(int n, int[][] edges) {
  2. List<Integer> result = new ArrayList<Integer>();
  3. if(n==0){
  4. return result;
  5. }
  6. if(n==1){
  7. result.add(0);
  8. return result;
  9. }
  10.  
  11. ArrayList<HashSet<Integer>> graph = new ArrayList<HashSet<Integer>>();
  12. for(int i=0; i<n; i++){
  13. graph.add(new HashSet<Integer>());
  14. }
  15.  
  16. for(int[] edge: edges){
  17. graph.get(edge[0]).add(edge[1]);
  18. graph.get(edge[1]).add(edge[0]);
  19. }
  20.  
  21. LinkedList<Integer> leaves = new LinkedList<Integer>();
  22. for(int i=0; i<n; i++){
  23. if(graph.get(i).size()==1){
  24. leaves.offer(i);
  25. }
  26. }
  27.  
  28. if(leaves.size()==0){
  29. return result;
  30. }
  31.  
  32. while(n>2){
  33. n = n-leaves.size();
  34.  
  35. LinkedList<Integer> newLeaves = new LinkedList<Integer>();
  36.  
  37. for(int l: leaves){
  38. int neighbor = graph.get(l).iterator().next();
  39. graph.get(neighbor).remove(l);
  40. if(graph.get(neighbor).size()==1){
  41. newLeaves.add(neighbor);
  42. }
  43. }
  44.  
  45. leaves = newLeaves;
  46. }
  47.  
  48. return leaves;
  49. }  

Python:

  1. class Solution(object):
  2. def findMinHeightTrees(self, n, edges):
  3. """
  4. :type n: int
  5. :type edges: List[List[int]]
  6. :rtype: List[int]
  7. """
  8. if n == 1:
  9. return [0]
  10.  
  11. neighbors = collections.defaultdict(set)
  12. for u, v in edges:
  13. neighbors[u].add(v)
  14. neighbors[v].add(u)
  15.  
  16. pre_level, unvisited = [], set()
  17. for i in xrange(n):
  18. if len(neighbors[i]) == 1: # A leaf.
  19. pre_level.append(i)
  20. unvisited.add(i)
  21.  
  22. # A graph can have 2 MHTs at most.
  23. # BFS from the leaves until the number
  24. # of the unvisited nodes is less than 3.
  25. while len(unvisited) > 2:
  26. cur_level = []
  27. for u in pre_level:
  28. unvisited.remove(u)
  29. for v in neighbors[u]:
  30. if v in unvisited:
  31. neighbors[v].remove(u)
  32. if len(neighbors[v]) == 1:
  33. cur_level.append(v)
  34. pre_level = cur_level
  35.  
  36. return list(unvisited)

C++:

  1. // Time: O(n)
  2. // Space: O(n)
  3.  
  4. class Solution {
  5. public:
  6. vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
  7. if (n == 1) {
  8. return {0};
  9. }
  10.  
  11. unordered_map<int, unordered_set<int>> neighbors;
  12. for (const auto& e : edges) {
  13. int u, v;
  14. tie(u, v) = e;
  15. neighbors[u].emplace(v);
  16. neighbors[v].emplace(u);
  17. }
  18.  
  19. vector<int> pre_level, cur_level;
  20. unordered_set<int> unvisited;
  21. for (int i = 0; i < n; ++i) {
  22. if (neighbors[i].size() == 1) { // A leaf.
  23. pre_level.emplace_back(i);
  24. }
  25. unvisited.emplace(i);
  26. }
  27.  
  28. // A graph can have 2 MHTs at most.
  29. // BFS from the leaves until the number
  30. // of the unvisited nodes is less than 3.
  31. while (unvisited.size() > 2) {
  32. cur_level.clear();
  33. for (const auto& u : pre_level) {
  34. unvisited.erase(u);
  35. for (const auto& v : neighbors[u]) {
  36. if (unvisited.count(v)) {
  37. neighbors[v].erase(u);
  38. if (neighbors[v].size() == 1) {
  39. cur_level.emplace_back(v);
  40. }
  41. }
  42. }
  43. }
  44. swap(pre_level, cur_level);
  45. }
  46.  
  47. vector<int> res(unvisited.begin(), unvisited.end());
  48. return res;
  49. }
  50. };

  

  

类似题目:

Course Schedule II

Course Schedule

Clone Graph

All LeetCode Questions List 题目汇总

[LeetCode] 310. Minimum Height Trees 最小高度树的更多相关文章

  1. [LeetCode] Minimum Height Trees 最小高度树

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  2. [LeetCode] 310. Minimum Height Trees 解题思路

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  3. leetcode@ [310] Minimum Height Trees

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  4. 310. Minimum Height Trees -- 找出无向图中以哪些节点为根,树的深度最小

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  5. 【LeetCode】310. Minimum Height Trees 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 BFS 相似题目 参考资料 日期 题目地址:http ...

  6. 310. Minimum Height Trees

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  7. [LeetCode] 310. Minimum Height Trees_Medium tag: BFS

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  8. [Swift]LeetCode310. 最小高度树 | Minimum Height Trees

    For an undirected graph with tree characteristics, we can choose any node as the root. The result gr ...

  9. 最小高度的树 Minimum Height Trees

    2018-09-24 12:01:38 问题描述: 问题求解: 毫无疑问的一条非常好的题目,采用的解法是逆向的BFS,也就是从叶子节点开始遍历,逐步向中心靠拢,最终留下的叶子节点就是答案. publi ...

随机推荐

  1. Windows 将FTP 映射到本地文件夹 --简化操作

    转载自yutiantongbu Windows 将FTP 映射到本地文件夹 --简化操作 1.右键我的电脑,选择映射网络驱动器 2.选择"连接到可用与存储文档和图片的网站" 3.接 ...

  2. JVM垃圾回收算法分析与演示【纯理论】

    继续接着上一次[https://www.cnblogs.com/webor2006/p/10729649.html]的来学习,上次在结尾处提到了JVM常见的GC算法,如下: 接下来则逐一的对其进行学习 ...

  3. Vuex 是什么?

    Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变   什么是"状态管 ...

  4. python通过LXML库读取xml命名空间

    xml实例版本: <a> <city:table xmlns:city="city"> <heilongjiang name="citys& ...

  5. 【python】raise_for_status()抛出requests.HTTPError错误

    1.首先看下面代码的运行情况 import requests res = requests.get("https://www.csdn.net/eee", headers=head ...

  6. docker-compose更新image命令

    docker-compose stop docker-compose up -d --build

  7. 【Selenium-WebDriver实战篇】selenium之使用Tess4J进行验证码图片识别内容

    ==================================================================================================== ...

  8. modbus-poll和modbus-slave工具的学习使用——环境搭建

    在modbus的学习工具中,非modbus-poll和modbus-slave莫属了,在电脑上模拟的过程中,两者缺一不可 ,当然还需要虚拟串口工具:Configure Virtual Serial P ...

  9. php web开发——文件夹的上传和下载

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  10. H5视频播放小结(video.js不好用!!!)

    近期在做一个H5的视频课堂,遇到了H5播放的需求,因为原生的video的样式不太理想,尤其是封面无法压住控制条,这就需要我们自定义播放控件. 于是,找了很近的插件,找到了用户比较多的video.js插 ...