码迷,mamicode.com
首页 > 其他好文 > 详细

310. Minimum Height Trees

时间:2016-07-05 06:22:04      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:

    /*
     * 310. Minimum Height Trees
     * 2016-3-29 by Mingyang
     * 同样的方法构建无向图
     * 这里运用的一个层层剥丝的方式,一层一层的来,去掉不要的
     * 我最先想到的解法是遍历的点,以每个点都当做根节点,算出高度,然后找出最小的,发现大家推崇的方法是一个类似剥洋葱的方法,
     * 就是一层一层的褪去叶节点,最后剩下的一个或两个节点就是我们要求的最小高度树的根节点,这种思路非常的巧妙,而且实现起来也不难,
     * 跟之前那到课程清单的题一样,我们需要建立一个图g,是一个二维数组,其中g[i]是一个一维数组,保存了i节点可以到达的所有节点。
     * 还需要一个一维数组d用来保存各个节点的入度信息,其中d[i]表示i节点的入度数。我们的目标是删除所有的叶节点,叶节点的入度为1,
     * 所以我们开始将所有入度为1的节点(叶节点)都存入到一个队列queue中,然后我们遍历每一个叶节点,通过图来找到和其相连的节点,
     * 将该节点的入度减1,如果该节点的入度减到1了,说明此节点也也变成一个叶节点了,加入队列中,再下一轮删除。那么我们删到什么时候呢,
     * 当节点数小于等于2时候停止,此时剩下的一个或两个节点就是我们要求的最小高度树的根节点啦
     */
     public List<Integer> findMinHeightTrees(int n, int[][] edges) {
            if (n == 1) return Collections.singletonList(0);
            List<Set<Integer>> adj = new ArrayList<Set<Integer>>(n);
            for (int i = 0; i < n; ++i) adj.add(new HashSet<Integer>());
            for (int[] edge : edges) {
                adj.get(edge[0]).add(edge[1]);
                adj.get(edge[1]).add(edge[0]);
            }
            List<Integer> leaves = new ArrayList<Integer>();
            for (int i = 0; i < n; ++i)
                if (adj.get(i).size() == 1) leaves.add(i);
            //这里是找到叶子节点,每一个叶子节点的上一层节点,砍掉回来的路
            while (n > 2) {
                n -= leaves.size();
                List<Integer> newLeaves = new ArrayList<Integer>();
                for (int i : leaves) {
                    int j = adj.get(i).iterator().next();
                    adj.get(j).remove(i);
                    if (adj.get(j).size() == 1) newLeaves.add(j);
                }
                leaves = newLeaves;
            }
            return leaves;
        }

 

310. Minimum Height Trees

标签:

原文地址:http://www.cnblogs.com/zmyvszk/p/5642199.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!