LeetCode 0310.最小高度树:拓扑排序秒了

【LetMeFly】310.最小高度树:拓扑排序秒了

力扣题目链接:https://leetcode.cn/problems/minimum-height-trees/

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

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

可选择树中任何一个节点作为根。当选择节点 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) 互不相同
    • 给定的输入 保证 是一棵树,并且 不会有重复的边

    方法一:拓扑排序

    根据图论我们知道,(非空)树的中心有一个或两个。

    原因小提示:

    树中最长路的中心有一个或两个。

    那么,我们来个拓扑排序不就好了?

    从叶节点开始“扔”,每次扔掉所有的叶节点节点。这样就会出现新的叶节点,再扔掉。…。一层一层,直到某层扔完时剩下一个或两个节点即为答案。

    拓扑排序怎么实现:

    使用一个数组degreedegree[i]表示与节点i相邻的边有几条,图论中称其为

    初始时将所有度为1的节点入队。

    每次将这一层的所有节点出队,对于出队的节点thisNode,它的所有相邻的节点的度减一。若度变成了1,则入队(新的叶节点get)。

    • 时间复杂度 O ( n ) O(n) O(n)
    • 空间复杂度 O ( n ) O(n) O(n)

    AC代码

    C++
    class Solution {
    public:
        vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
            if (n == 1) {  // 这里不要忘了!要不然degree不为1
                return {0};
            }
            vector<int> degree(n);
            vector<vector<int>> graph(n);
            for (vector<int>& v : edges) {
                degree[v[0]]++;
                degree[v[1]]++;
                graph[v[0]].push_back(v[1]);
                graph[v[1]].push_back(v[0]);
            }
            queue<int> q;
            for (int i = 0; i < n; i++) {
                if (degree[i] == 1) {
                    q.push(i);
                }
            }
            int remainNode = n;
            while (remainNode > 2) {
                for (int _ = q.size(); _ > 0; _--) {
                    remainNode--;
                    int thisNode = q.front();
                    q.pop();
                    for (int nextNode : graph[thisNode]) {
                        degree[nextNode]--;
                        if (degree[nextNode] == 1) {
                            q.push(nextNode);
                        }
                    }
                }
            }
            vector<int> ans = {q.front()};
            q.pop();
            if (q.size()) {
                ans.push_back(q.front());
            }
            return ans;
        }
    };
    
    Python
    from typing import List
    
    class Solution:
        def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
            if n == 1:
                return [0]
            degree = [0] * n
            graph = [[] for _ in range(n)]
            for x, y in edges:
                degree[x] += 1
                degree[y] += 1
                graph[x].append(y)
                graph[y].append(x)
            q = [i for i, d in enumerate(degree) if d == 1]
            remainNode = n
            while remainNode > 2:
                tempQ = []
                for thisNode in q:
                    remainNode -= 1
                    for nextNode in graph[thisNode]:
                        degree[nextNode] -= 1
                        if degree[nextNode] == 1:
                            tempQ.append(nextNode)
                q = tempQ
            return q
    

    同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
    Tisfy:https://letmefly.blog.csdn.net/article/details/136790299

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/464794.html

    如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

    相关文章

    JavaScript 进阶(一)

    一、作用域 作用域&#xff08;scope&#xff09;规定了变量能够被访问的“范围”&#xff0c;离开了这个“范围”变量便不能被访问。 作用域分为&#xff1a; 局部作用域 、全局作用域。 1.1局部作用域 局部作用域分为函数作用域和块作用域。 1. 函数作用域&#xff1a; 在函数…

    力扣刷题Days20-151. 反转字符串中的单词(js)

    目录 1,题目 2&#xff0c;代码 1&#xff0c;利用js函数 2&#xff0c;双指针 3&#xff0c;双指针加队列 3&#xff0c;学习与总结 1&#xff0c;正则表达式 / \s /&#xff1a; 2&#xff0c;结合使用 split 和正则表达式&#xff1a; 1,题目 给你一个字符串 s &am…

    [漏洞分析]Fortinet FortiNAC CVE-2022-39952简析

    Fortinet FortiNAC CVE-2022-39952简析 一、影响版本二、概况三、利用CVE-2022-39952四、POC 一、影响版本 FortiNAC 9.4.0 FortiNAC 9.2.0 - 9.2.5 FortiNAC 9.1.0 - 9.1.7 FortiNAC 8.3 - 8.8 二、概况 Fortinet 在其安全公告中表示&#xff0c;他们在keyUpload script…

    深入解析红黑树(RB-Tree):原理、操作及应用

    文章目录 一、红黑树的特点与性质二、红黑树的实现1、实现红黑树的插入操作2、红黑树的验证方法a. Check 函数b. IsBalance 函数 红黑树作为一种自平衡的二叉搜索树&#xff0c;在计算机科学领域中占据着重要的地位。它的设计旨在在维持树的平衡性的同时&#xff0c;保证各种操…

    【JavaScript】JavaScript 运算符 ⑤ ( 赋值运算符 | 基础赋值运算符 与 复合赋值运算符 )

    文章目录 一、JavaScript 赋值运算符1、赋值运算符 概念2、基础赋值运算符 与 复合赋值运算符3、复合赋值运算符4、完整代码示例 一、JavaScript 赋值运算符 JavaScript 赋值运算符种类 : 基础赋值运算符 : 等于 : ; 复合赋值运算符 : 加等 : 减等 : -乘等 : *除等 : /取模等…

    基于springboot+vue的房屋交易平台

    博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

    App拉新必备!Xinstall渠道追踪,让每一分钱都花在刀刃上

    在移动互联网时代&#xff0c;App已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;对于App开发者来说&#xff0c;如何有效地进行拉新&#xff0c;提高用户留存率&#xff0c;一直是一个难题。而渠道追踪&#xff0c;作为App推广过程中的重要环节&#xff0c;往往被忽…

    029—pandas 遍历行非向量化修改数据

    前言 在 pandas 中&#xff0c;向量化计算是指利用 pandas 对象的内置方法和函数&#xff0c;将操作应用到整个数据结构的每个元素&#xff0c;从而在单个操作中完成大量的计算。 但在一些需求中&#xff0c;我们无法使用向量化计算&#xff0c;就需要迭代操作&#xff0c;本例…

    前端三件套 | 综合练习:模拟抽奖活动,实现一个简单的随机抽取并显示三名获胜者

    随机运行结果如下&#xff1a; 参考代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><tit…

    通俗易懂的Python循环讲解

    循环用于重复执行一些程序块。从上一讲的选择结构&#xff0c;我们已经看到了如何用缩进来表示程序块的隶属关系。循环也会用到类似的写法。 for循环 for循环需要预先设定好循环的次数(n)&#xff0c;然后执行隶属于for的语句n次。 基本构造是 for 元素 in 序列: statemen…

    常用芯片学习——BME280芯片

    BME280 温湿度气压传感器 芯片介绍 BME280是基于成熟传感原理的组合数字湿度、压力和温度传感器。该传感器块采用极为紧凑的金属盖LGA封装&#xff0c;占地面积仅为2.5x2.5mm2&#xff0c;高度为0.93mm。该传感器提供I2C以及SPI接口。它的小尺寸和低功耗允许在电池驱动的设备…

    如何写好Stable Diffusion的prompt

    Stable Diffusion是一种强大的文本到图像生成模型&#xff0c;其效果在很大程度上取决于输入的提示词&#xff08;Prompt&#xff09;。以下是一些关于如何编写有效的Stable Diffusion Prompt的秘诀&#xff1a; 明确描述&#xff1a;尽量清晰地描述你想要的图像内容。使用具体…

    算法第二十九天-最长公共子序列

    最长公共子序列 题目要求 解题思路 求这两个数组或者字符串的最长公共子序列问题&#xff0c;肯定要用到动态规划。 首先区分两个概念&#xff1a;子序列可以是不连续的&#xff1b;子数组&#xff08;子字符串&#xff09;是需要连续的&#xff1b;另外&#xff0c;动态规划…

    2024年腾讯云免费服务器4核8G配置申请

    腾讯云免费服务器4核8G配置申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云服务器网txyfwq.com分享2024年最新腾…

    OpenAI Q-Star:AGI距离自我意识越来越近

    最近硅谷曝出一份54页的内部文件&#xff0c;揭露了去年OpenAI宫斗&#xff0c;导致Altman&#xff08;奥特曼&#xff09;差点离职的神秘项目——Q-Star&#xff08;神秘代号Q*&#xff09;。 根据该文件显示&#xff0c;Q-Star多模态大模型拥有125万亿个参数&#xff0c;比现…

    【GPT-SOVITS-01】源码梳理

    说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…

    RuiYi-Vue开源项目1-下载并实现运行RuiYi-Vue项目

    下载并实现运行RuoYi项目 RuiYi-Vue介绍环境需要下载项目项目配置后端项目配置前端项目配置 启动后前端登录页面截图 RuiYi-Vue介绍 RuoYi-Vue 是一个 Java EE 企业级快速开发平台&#xff0c;基于经典技术组合&#xff08;Spring Boot、Spring Security、MyBatis、Jwt、Vue&a…

    clickhouse学习笔记01(小滴课堂)

    老王经历-数据库架构演变历史 你是否能分清OLTP和OLAP系统 急速掌握-数据库里面行存储和列式存储 新一代列式存储ClickHouse介绍和应用场景说明 Linux服务器容器化部署ClickHouse实战 记得要在安全组里配置开放端口号。 到这我们就安装完了。 简单使用&#xff1a; 创建你的第…

    P1093 [NOIP2007 普及组] 奖学金

    [NOIP2007 普及组] 奖学金 题目背景 NOIP2007 普及组 T1 题目描述 某小学最近得到了一笔赞助&#xff0c;打算拿出其中一部分为学习成绩优秀的前 5 5 5 名学生发奖学金。期末&#xff0c;每个学生都有 3 3 3 门课的成绩&#xff1a;语文、数学、英语。先按总分从高到低排…

    关于volatile与指令重排序的探讨

    写在开头 在之前的学习我们了解到&#xff0c;为了充分利用缓存&#xff0c;提高程序的执行速度&#xff0c;编译器在底层执行的时候&#xff0c;会进行指令重排序的优化操作&#xff0c;但这种优化&#xff0c;在有些时候会带来 有序性 的问题。 那何为有序性呢&#xff1f;…