zoukankan      html  css  js  c++  java
  • 0310. Minimum Height Trees (M)

    Minimum Height Trees (M)

    题目

    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.

    Given a tree of n nodes labelled from 0 to n - 1, and an array of n - 1 edges where edges[i] = [ai, bi] indicates that there is an undirected edge between the two nodes ai and bi in the tree, you can choose any node of the tree as the root. When you select a node x as the root, the result tree has height h. Among all possible rooted trees, those with minimum height (i.e. min(h)) are called minimum height trees (MHTs).

    Return a list of all MHTs' root labels. You can return the answer in any order.

    The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

    Example 1:

    Input: n = 4, edges = [[1,0],[1,2],[1,3]]
    Output: [1]
    Explanation: As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT.
    

    Example 2:

    Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
    Output: [3,4]
    

    Example 3:

    Input: n = 1, edges = []
    Output: [0]
    

    Example 4:

    Input: n = 2, edges = [[0,1]]
    Output: [0,1]
    

    Constraints:

    • 1 <= n <= 2 * 10^4
    • edges.length == n - 1
    • 0 <= ai, bi < n
    • ai != bi
    • All the pairs (ai, bi) are distinct.
    • The given input is guaranteed to be a tree and there will be no repeated edges.

    题意

    在给定的无向无环图中确定一个根结点,使得得到的树的高度最小。

    思路

    从最外层的叶结点开始一层一层向里面“剥”,直到只剩最里面的1或2个结点即为答案。具体方法是:根据信息构建图,并把所有叶结点加入到队列中;依次出队,删去叶结点,更新叶结点连接的所有结点,并将新生成的叶结点入队;重复直到只剩1或2个结点。

    另一种可行的方法是,先求无向图的直径,即叶结点到叶结点的最长路径,再求这个路径中间的1或2个结点即为答案。求直径的具体方法:任选一个结点,用DFS/BFS找到离它最远的结点A,再从A出发,找到离A最远的结点B,A-B构成的路径即为直径。


    代码实现

    Java

    class Solution {
        public List<Integer> findMinHeightTrees(int n, int[][] edges) {
            if (n == 1) {
                return new ArrayList<Integer>() {
                    {
                        add(0);
                    }
                };
            }
          
            Map<Integer, Set<Integer>> g = new HashMap<>();
            Queue<Integer> q = new LinkedList<>();
    
            for (int i = 0; i < edges.length; i++) {
                int a = edges[i][0], b = edges[i][1];
                g.putIfAbsent(a, new HashSet<>());
                g.putIfAbsent(b, new HashSet<>());
    
                g.get(a).add(b);
                g.get(b).add(a);
            }
    
            for (int i = 0; i < n; i++) {
                if (g.get(i).size() == 1) {
                    q.offer(i);
                }
            }
    
            while (n > 2) {
                int size = q.size();
                for (int i = 0; i < size; i++) {
                    int x = q.poll();
                    for (int y : g.get(x)) {
                        g.get(y).remove(x);
                        if (g.get(y).size() == 1) {
                            q.offer(y);
                        }
                    }
                }
                n -= size;
            }
    
            return new ArrayList<>(q);
        }
    }
    
  • 相关阅读:
    分享一个MySQL分库分表备份脚本(原)
    mysql配置以及性能优化(转)
    redis 集群配置实战
    Debian安装fail2ban来防止扫描
    关于微信小程序,一些想法
    读书笔记:《HTML5开发手册》-- 现存元素的变化
    linux下如何使用vnstat查看服务器带宽流量统计
    在iOS微信浏览器中自动播放HTML5 audio(音乐)的2种正确方式
    VS自定义项目模板:[4]自定义模板的分组
    VS自定义项目模板:[3]创建自定义模板
  • 原文地址:https://www.cnblogs.com/mapoos/p/13929468.html
Copyright © 2011-2022 走看看