leetcode 310 最小高度树

news2024/10/6 14:27:09

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

给你一棵包含 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) 互不相同
给定的输入 保证 是一棵树,并且 不会有重复的边

思路1, 先根据图的叶子节点(对应的边为1),进行广度遍历,遍历到最后一层,则显然以最后一层为根节点的树是最小高度树

class Solution:
    def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
        if len(edges) == 0:
            return [0]
        degree = [set() for i in range(n)]
        visited = [0]*n
        for x in edges:
            degree[x[0]].add(x[1])
            degree[x[1]].add(x[0])
        q = collections.deque()
        for i in range(n):
            if len(degree[i]) == 1:  ## 根据题目条件,这儿不会有为 0 的
                visited[i] = 1
                q.append(i)
        ## 根据叶子节点一层一层遍历,最后一层就是结果
        while len(q) > 0:
            len_q = len(q)
            temp1, neighbor = [], set()
            for i in range(len_q):
                top = q.popleft()
                temp1.append(top)
                for x in degree[top]:
                    degree[x].remove(top)
                    if visited[x] == 0:
                        neighbor.add(x)
            if len(neighbor) == 0:
                return temp1
            for x in neighbor:
                if len(degree[x]) <= 1:  ## 为 叶子节点的入队列
                    q.append(x)
                    visited[x] = 1
        return []

思路2,以任意节点 p,利用广度优先搜索或者深度优先搜索找到以 p为起点的最长路径的终点 x;
以节点 x 出发,找到以 x为起点的最长路径的终点 y;
x 到 y 之间的路径即为图中的最长路径,找到路径的中间节点即为根节点。

import copy
class Solution:
    ## 查找 graph 里面距离 start 最远的节点
    def bfs(self, n, graph, start):
        visited  = [0]*n
        visited[start] = 1
        q = collections.deque()
        q.append(start)
        res = [start]
        while len(q) > 0:
            len_q = len(q)
            for i in range(len_q):
                top = q.popleft()
                for x in graph[top]:
                    if visited[x] == 0:
                        q.append(x)
                        res.append(x)
                        visited[x] = 1
                        graph[x].remove(top)
        return res[-1]

    ## 思路, 找出最长路径,然后找出其中的中间节点
    def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
        if len(edges) == 0:
            return [0]
        graph = [set() for i in range(n)]
        for x in edges:
            graph[x[0]].add(x[1])
            graph[x[1]].add(x[0])
        graph1 = copy.deepcopy(graph)
        ## 随机用一个点, 得到距离其最远的节点, 设为 node1,  再根据 node1 找距离 node1 最远的节点 node2
        ## node1 与 node2 是一条最长的路径
        node1 = self.bfs(n, graph1, 0)
        graph1 = copy.deepcopy(graph)
        node2 = self.bfs(n, graph1, node1)  ## node1, node2 为图中的最长路径
        father = [0]*n
        q = collections.deque([node1])
        visited = [0]*n
        visited[node1] = 1
        ## 广度遍历, 记录每个节点的 father 节点
        while len(q) > 0:
            len_q = len(q)
            for i in range(len_q):
                top = q.popleft()
                if top == node2:
                    break
                for x in graph[top]:
                    if visited[x] == 0:
                        q.append(x)
                        visited[x] = 1
                        father[x] = top
                        graph[x].remove(top)
        tmp = [node2]
        node = node2
        while node != node1:
            node = father[node]
            tmp.append(node)
        if len(tmp)%2 == 0:
            return [tmp[int((len(tmp)-1)/2)], tmp[int((len(tmp))/2)]]
        else:
            return [tmp[int(len(tmp)/2)]]

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第二十九天 | 回溯算法总结

​ 代码随想录算法训练营第二十九天 | 回溯算法总结 1. 组合问题 1.1 组合问题 在77. 组合中&#xff0c;我们开始用回溯法解决第一道题目&#xff1a;组合问题。 回溯算法跟k层for循环同样是暴力解法&#xff0c;为什么用回溯呢&#xff1f;回溯法的魅力&#xff0c;用递…

excel常用的几个函数

1、MID函数 通常用来返回返回指定字符串中的子串。 函数公式&#xff1a; MID(string, starting_at, extract_length) String&#xff08;必填&#xff09;&#xff1a;包含要提取字符的文本字符串 starting_at&#xff08;必填&#xff09;&#xff1a;文本中要提取的第一个字…

Tomcat及jdk安装下载及环境配置(超超超详解)

我是看了两篇博客安装配置好的 jdk 最详细jdk安装以及配置环境&#xff08;保姆级教程&#xff09;_安装jdk需要配置环境变量吗-CSDN博客 tomcat Tomcat的下载安装与配置及常见问题处理【Win11】 - 鞠雨童 - 博客园 (cnblogs.com) 本篇文章是我解决了很多朋友的tomcat配置问题总…

基于RIP的MGRE实验

题目及视图&#xff1a; 实验要求&#xff1a; 1.R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址 2.R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证 R2与R5之间使用ppp的CHAP认证&#xff0c;R5为主认证方 R3与R5之间使用HDLC封装 3.R1…

【C++学习笔记】引用

1. 概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空 间&#xff0c;它和它引用的变量共用同一块内存空间。 比如&#xff1a;孙悟空&#xff0c;有人叫弼马温&#xff0c;也有人称为齐天大圣。 1.1 使用方…

计算机毕业设计 基于SpringBoot智慧养老中心管理系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

粤嵌实训医疗项目--day01(Vue+SpringBoot)

目录 一、创建工作空间及配置Maven环境 二、创建springboot项目整合web操作 三、http请求参数获取及登录页面访问操作 四、数据库设计、数据库创建及导入sql 五、使用mybatis-plus逆向工程生成代码【vaccinum】 六、JavaEE三层架构概念及user查询实现 七、mybatis-plus逆…

安装与脏数据绕过_安全狗

1安全狗 1.1 环境准备 安全狗safedogwzApacheV3.5.exe&#xff0c;安装步骤省略&#xff0c; pikachu环境&#xff1a;https://zhuanlan.zhihu.com/p/568493971 安装注意事项&#xff1a;安装完后php和web服务都需要重启 注意事项&#xff1a;服务名php版本保持一致 安装过…

UG\NX二次开发 获取调色板CDF文件的内容

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 感谢粉丝订阅 感谢 迈克尔.卓别煷 订阅本专栏,非常感谢。 简介 UG\NX二次开发 获取调色板CDF文件的内容 文件->首选项->调色板 效果 代码 #include "me.hpp" #

使用Simple JWT提供认证服务(详细介绍access_token和refresh_token的使用)

文章目录 基本概念JSON Web Token&#xff08;JWT&#xff09;Simple JWT 主要用途Cookie、Session、Token的区别CookieSessionToken Token续签access_token 和 refresh_token时效设置 基本概念 JSON Web Token&#xff08;JWT&#xff09; JSON Web Token&#xff08;JWT&am…

探索大数据时代的关键技术:数据挖掘、可视化和数据仓库

文章目录 &#x1f31f; 大数据和数据分析技术&#x1f34a; 引言&#x1f34a; 数据挖掘&#x1f34a; 数据可视化&#x1f34a; 数据仓库&#x1f34a; 结论 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里…

【Linux基础】详谈Shell运行原理------王婆传媒(高重复率面试题)

目录 &#x1f4a7;前言 &#x1f4a6;Shell的运行原理 &#x1f449;Shell的基本概念与作用 &#x1f449;原理的展示与剖析 &#x1f449;Shell外壳感性理解【一门亲事】 &#x1f4a7;总结 &#x1f4a7;共勉 &#x1f4a7;前言 在之前的 Linux 讲解中&#xff0c;主要说…

【管理运筹学】第 10 章 | 排队论(2,到达时间间隔的分布和服务时间的分布)

文章目录 引言一、普阿松分布二、负指数分布三、爱尔朗分布 引言 解决排队问题&#xff0c;首先要根据原始资料做出顾客到达时间间隔和服务时间的经验分布&#xff0c;然后按照统计学的方法&#xff08;如 χ 2 \chi^2 χ2 检验&#xff09;以确定属于哪种分布理论&#xff0…

JS数组方法合集(含应用场景)

1.Array.push() 向数组的末尾添加一个或多个元素&#xff0c;并返回新的数组长度。原数组改变 const arr ["apple", "orange", "grape"]; const arr_length arr.push("banana");console.log("arr", arr, "arr_leng…

JOSEF约瑟 JHOK-ZBM1;JHOK-ZBL1多档切换式漏电(剩余)继电器 面板导轨安装

系列型号&#xff1a; JHOK-ZBL多档切换式漏电&#xff08;剩余&#xff09;继电器&#xff08;导轨&#xff09; JHOK-ZBL1多档切换式漏电&#xff08;剩余&#xff09;继电器 JHOK-ZBL2多档切换式漏电&#xff08;剩余&#xff09;继电器 JHOK-ZBM多档切换式漏电&#xf…

【算法训练-动态规划 一】【应用DP问题】零钱兑换、爬楼梯、买卖股票的最佳时机I、打家劫舍

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【动态规划】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

springBoot--web--favicon规则

在静态资源目录中找favicon.icon 推荐图标工具 favicon使用 在静态资源中放入下载好的图片,改名为favicon.ico

互联网医院|互联网医疗模式已从概念走向实体建设阶段

近年来&#xff0c;医疗服务领域新形态不断涌现&#xff0c;“互联网医疗”作为其中突出的一种&#xff0c;在挂号结算、远程诊疗、咨询服务等方面进行了不少探索&#xff0c;而早在2015年全国互联网医院成立&#xff0c;标志着“互联网医疗”模式已经从概念走向了实体建设阶段…

【Arduino TFT】Arduino uzlib库,用于解压gzip流,解析和风天气返回数据

忘记过去&#xff0c;超越自己 ❤️ 博客主页 单片机菜鸟哥&#xff0c;一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-10-21 ❤️❤️ 本篇更新记录 2023-10-21 ❤️&#x1f389; 欢迎关注 &#x1f50e;点赞 &#x1f44d;收藏 ⭐️留言&#x1f4dd;&#x1f64…