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);
        }
    }
    
  • 相关阅读:
    USASO Greedy Gift Givers
    Mat 类型用法
    OpenCV错误:Unhandled exception at 0x0133bc63 ....0xC0000005: Access violation reading location 0x00000004.
    C++ seekp 函数文件流跳转功能产生数据覆盖问题解决
    C++中文件名称必须是C风格的char*格式
    char*, char[] ,CString, string的转换
    Visual Stdio 2008 最大内存分配块大小问题: 使用new 分配连续723M内存 出错 std::bad_alloc at memory location 0x0013e0b8
    string类型转化为char*错误: error C2440: '=' : cannot convert from 'const char *' to 'char *'
    Mat 和 IplImage、CvMat格式的互相转换
    指针数组和数组指针
  • 原文地址:https://www.cnblogs.com/mapoos/p/13929468.html
Copyright © 2011-2022 走看看