【LeetCode】310. Minimum Height Trees

题目链接


思路

我想到了n个点构成树,那么一定会有n-1条边,构成的树深度最大的情况发生在所有点位于一条链上,此时深度为 n/2 n/2+1 ,这取决于n的奇偶性。

树深度最浅的情况发生在一个根节点,所有其它节点都与根节点直接相连,此时深度为2。

我还发现一个规律,就是叶子节点的数目+树的最长路径为一定值,为节点数+2。这样统计出有多少个叶子节点后,再走最长路径的一半所到达的节点就是根节点。但是这个思路不能保证走最长路径的一半是正确的路径,所以这个方法没有再进行下去。

Hot解法是利用bfs,从叶子节点开始访问,每一次循环都把与叶子节点直接相连的节点访问,并判断它们是否成为新的叶子节点。同时从叶子节点出发,最终共同到达的节点一定是根节点。


代码

vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
        vector<int> re;
        if (n<=2){
            for (int i=0;i<n;++i){
                re.push_back(i);
            }
            return re;
        }
        vector<unordered_set<int>> graph(n);
        for (int i=0;i<edges.size();++i){
            auto p = edges[i];
            graph[p.first].insert(p.second);
            graph[p.second].insert(p.first);
        }
        //find all leaves
        queue<int> leaves;
        for (int i=0;i<n;++i){
            if (graph[i].size()==1) leaves.push(i);
        }

        while(n>2){
            n = n - leaves.size();
            queue<int> newLeaves;
            while (!leaves.empty()){
                int curLeaf = leaves.front();
                leaves.pop();
                int nextToLeaf = *(graph[curLeaf].begin());
                graph[nextToLeaf].erase(curLeaf);
                if (graph[nextToLeaf].size()==1){
                    newLeaves.push(nextToLeaf);
                }
            }
            leaves = newLeaves;
        }
        while (!leaves.empty()){
            int leaf = leaves.front();
            leaves.pop();
            re.push_back(leaf);
        }
        return re;
    }

细节

第一次我用向量存储每个节点的相邻节点,后来发现vector删除指定大小的元素不是很方便,vector只有两种删除方式,erase是删除基于位置的,pop_back()只能删除最后一个元素。所以后来改用set

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值