LeetCode-310 最小高度树

简介: LeetCode-310 最小高度树

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/minimum-height-trees

题目描述

树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。

给你一棵包含 n 个节点的树,标记为 0 到 n - 1 。给定数字 n 和一个有 n - 1 条无向边的 edges 列表(每一个边都是一对标签),其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间存在一条无向边。

可选择树中任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树中,具有最小高度的树(即,min(h))被称为 最小高度树 。

请你找到所有的 最小高度树 并按 任意顺序 返回它们的根节点标签列表。

树的 高度 是指根节点和叶子节点之间最长向下路径上边的数量。

 

示例 1:

 

 

输入:n = 4, edges = [[1,0],[1,2],[1,3]]

输出:[1]

解释:如图所示,当根是标签为 1 的节点时,树的高度是 1 ,这是唯一的最小高度树。

示例 2:

 

 

输入:n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]

输出:[3,4]

 

提示:

1 <= n <= 2 * 104

edges.length == n - 1

0 <= ai, bi < n

ai != bi

所有 (ai, bi) 互不相同

给定的输入 保证 是一棵树,并且 不会有重复的边

 

解题思路

最初使用的是对于每一个结点进行dfs求出最小树高度,时间复杂度为O(n2),不出所料超时了。由于没有想到根结点会是最长路径的中点这个规律,所以使用了拓扑的思路,时间复杂度有点高。

基本思路是每次都减除叶子结点,当某一刻减除叶子结点后树为空了,那么上一次减除的叶子结点就是最小高度树的根,可能是一个也可能是两个。

代码展示

 

class Solution {
public:
    vector<vector<int>> vviRelation;
    int iMin;
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        vector<int> viRet, viDu(n, 0);
        vviRelation.resize(n);
        unordered_set<int> setiNode;
        for(int i = 0; i < n; i++)
            setiNode.insert(i);
        for(auto iter: edges)
        {
            vviRelation[iter[0]].push_back(iter[1]);
            vviRelation[iter[1]].push_back(iter[0]);
            viDu[iter[0]]++;
            viDu[iter[1]]++;
        }
        while(!setiNode.empty())
        {
            viRet.resize(0);
            for(auto iter: setiNode)
            {
                if(viDu[iter] == 1 || viDu[iter] == 0)
                {
                    viDu[iter] = -1;
                    viRet.push_back(iter); 
                }
            }
            for(auto iter: viRet)
            {
                setiNode.erase(iter);
                for(auto iter2: vviRelation[iter])
                {
                    viDu[iter2]--;
                }
            }
        }
        return viRet;
    }
};

运行结果

 

相关文章
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
55 4
|
4月前
|
Python
【Leetcode刷题Python】538. 把二叉搜索树转换为累加树
LeetCode上538号问题"把二叉搜索树转换为累加树"的Python实现,使用反向中序遍历并记录节点值之和来更新每个节点的新值。
25 3
|
7月前
|
算法 C语言 容器
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(下)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
69 7
|
7月前
|
C语言
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(中)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
59 1
|
7月前
|
算法 C语言 C++
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(上)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
46 1
|
7月前
LeetCode———100——相同的树
LeetCode———100——相同的树
|
7月前
力扣337.打家劫舍3(树形dp)
力扣337.打家劫舍3(树形dp)
|
6月前
|
SQL 算法 数据可视化
LeetCode题目99:图解中叙遍历、Morris遍历实现恢复二叉树搜索树【python】
LeetCode题目99:图解中叙遍历、Morris遍历实现恢复二叉树搜索树【python】
|
6月前
|
存储 SQL 算法
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
|
6月前
|
存储 算法 数据可视化
python多种算法对比图解实现 验证二叉树搜索树【力扣98】
python多种算法对比图解实现 验证二叉树搜索树【力扣98】