LeetCode_310最小高度树

对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。

格式

该图包含 n 个节点,标记为 0 到 n - 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。

你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里。
在这里插入图片描述
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-height-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

学习的别人思路代码
原文链接:https://leetcode-cn.com/problems/minimum-height-trees/solution/javati-jie-bfssi-lu-hen-qing-xi-by-lemon-lc/

class Solution {
    /*
     * 解题思路:既然要求最小高度,那么从我们直觉来看,结点肯定是在最内部的,因为题目说了是无向图,所以越靠近边缘,高度肯定就会越大,
     * 最终的结点就是位于最中间的1个或2个结点。
     *
     * 1、首先对于数据进行初始化,这里使用degree数组来描述当前结点的度(因为我们每次都是要从边缘进行逐层的删除,而边缘就是度为1的结点)
     *    并且使用邻接表来存储和当前结点相邻的结点。
     * 2、将度为1的结点(边缘结点)插入到队列中,我们这里使用一个List<Integer> res来存每一层的结点,最后一次插入的所有结点就一定是最后一层的结点
     *  (也就是我们需要的最内部层的结点)。
     * 3、返回res数组即可。   
    */
    public List<Integer> findMinHeightTrees(int n, int[][] edges) {
        List<Integer> res = new ArrayList<Integer>();
        if (n==1) {
            res.add(0);
            return res;
        }
        //构造邻接表
        List<Set<Integer>> matrixList = new ArrayList<Set<Integer>>();
        //节点的度
        int[] degree = new int[n];
        for(int i=0;i<n;i++){
            matrixList.add(new HashSet<Integer>());
        }
        for(int i=0;i<edges.length;i++){
            int row = edges[i][0];
            int col = edges[i][1];
            matrixList.get(row).add(col);
            matrixList.get(col).add(row);
            degree[row] = degree[row]+1;
            degree[col] = degree[col]+1;
        }
        Queue<Integer> queue = new LinkedList<Integer>();
        for(int i=0;i<n;i++){
            if(degree[i]==1){
                queue.offer(i);
                degree[i] = -1;//相当于删除
            }
        }
        //进行bfs遍历,不断删除度为0的节点
        while(!queue.isEmpty()){
            res.clear();
            int size = queue.size();
            for (int j = 0; j < size; j++) {
                int curNode = queue.poll();
                res.add(curNode);
                for (int node : matrixList.get(curNode)) {
                    degree[node]--;
                    if (degree[node] == 1) {
                        queue.add(node);
                    }
                }
            }
        }
        return res;
    }
}

暴力法,会超时

class Solution {
    class Helper{
        int root;//根节点的值
        int deep;//根节点对应的树的深度值
        Helper(){}
        Helper(int root,int deep){
            this.root = root;
            this.deep = deep;
        }
    }
    public int min_value = Integer.MAX_VALUE;
    /*
    * 基本思路:(超时)
    * 1、根据输入的边的信息构造无向图矩阵(超时50/66),构造邻接表(63/66)
    * 2、采用回溯法,进行bfs遍历,同时记录下遍历的深度,存入list中.
    *    在遍历过程中维护一个全局最小深度值,一旦超过深度,直接返回.加快速度
    * 3、对list中的值进行判断,将合法的值返回
    */
    public List<Integer> findMinHeightTrees2(int n, int[][] edges) {
        List<Helper> list = new ArrayList<Helper>();
        //构造邻接表
        List<Set<Integer>> matrixList = new ArrayList<Set<Integer>>();
        for(int i=0;i<n;i++){
            matrixList.add(new HashSet<Integer>());
        }
        for(int i=0;i<edges.length;i++){
            int row = edges[i][0];
            int col = edges[i][1];
            matrixList.get(row).add(col);
            matrixList.get(col).add(row);
        }
        //进行bfs遍历
        for(int i=0;i<n;i++){
            boolean[] visit = new boolean[n];//判断该节点是否访问过
            Queue<Integer> queue = new LinkedList<Integer>();
            queue.offer(i);
            visit[i] = true;
            bfs(queue,1,1,i,matrixList,visit,list);
        }
        //对list中的值进行合法性判断
        List<Integer> res = new ArrayList<Integer>();
        for(Helper hp : list){
            if(hp.deep==min_value){
                res.add(hp.root);
            }
        }
        return res;
    }

    /*
    * queue代表同一层的所有节点值队列
    * deep以root为根节点的当前树的深度
    * num遍历的节点个数
    * root根节点(一但确定就不改变)
    */
    public void bfs(Queue<Integer> queue, int deep, int num, int root, List<Set<Integer>> matrixList, boolean[] visit, List<Helper> list){
        if(deep>min_value) return;
        if(num==visit.length){//所有节点遍历完
            min_value = Math.min(min_value,deep);
            Helper helper = new Helper(root,deep);
            list.add(helper);
            return;
        }
        //进行bfs
        int size = queue.size();
        int n = 0;
        while(n<size){
            int v = queue.poll();
            for(Integer value : matrixList.get(v)){
                if(!visit[value]){
                    queue.offer(value);
                    visit[value] = true;
                    num++;
                }
            }
            n++;
        }
        bfs(queue,deep+1,num,root,matrixList,visit,list);
    }
}
发布了250 篇原创文章 · 获赞 0 · 访问量 1271

猜你喜欢

转载自blog.csdn.net/qq_36198826/article/details/103806710
今日推荐