0
点赞
收藏
分享

微信扫一扫

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;
    }
};
举报

相关推荐

0 条评论