LeetCode 310 最小高度数[拓扑排序 BFS] HERODING的LeetCode之路

Posted HERODING23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 310 最小高度数[拓扑排序 BFS] HERODING的LeetCode之路相关的知识,希望对你有一定的参考价值。


解题思路

这道题如果用正常的写作思路,即遍历所有的节点作为根节点,然后DFS,找出最小高度,思路很清晰,但是会超时。参考了题解中最高赞的java实现思路,它采用了一种逆向思维,本质上是拓扑排序。解题思路是从叶子节点出发,农村包围城市,一步步找到最终的根节点集合,为什么从叶子节点出发就一定是正确的呢?因为叶子节点永远在最外面,如果以叶子节点为根,那么树的高度为叶子+根+…+叶子,总是要高于根+…+叶子,所以从叶子节点出发到根才能得到最短高度。基于BFS,每次都把当前的叶子节点遍历并剪枝,得到新的叶子节点放入队列中,直到无法剪枝,这时候队列中的节点即为最小高度树的根节点,代码如下:

代码

class Solution 
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) 
        vector<int> res;
        if(n == 1) 
            res.push_back(0);
            return res;
        
        vector<int> degree(n, 0);
        vector<vector<int>> tree(n);
        // 更新每个节点的度,构建树
        for(int i = 0; i < edges.size(); i ++) 
            degree[edges[i][0]] ++;
            degree[edges[i][1]] ++;
            tree[edges[i][0]].push_back(edges[i][1]);
            tree[edges[i][1]].push_back(edges[i][0]);
        
        queue<int> q;
        // 取出所有叶子节点
        for(int i = 0; i < n; i ++) 
            if(degree[i] == 1) 
                q.push(i);
            
        
        // bfs
        while(!q.empty()) 
            int size = q.size();
            res.clear();
            for(int i = 0; i < size; i ++) 
                int cur = q.front();
                q.pop();
                res.push_back(cur);
                // 剪枝
                degree[cur] --;
                for(auto node : tree[cur]) 
                    degree[node] --;
                    // 把新的叶子节点放入队列中
                    if(degree[node] == 1) 
                        q.push(node);
                    
                
            
        
        return res;
    
;

以上是关于LeetCode 310 最小高度数[拓扑排序 BFS] HERODING的LeetCode之路的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 310. Minimum Height Trees 最小高度树(中等)

leetcode.310最小高度树

LeetCode 310. 最小高度树

LeetCode 310. 最小高度树

LeetCode 310. 最小高度树

LeetCode 310. 最小高度树