LeetCode 310 最小高度树

题目信息

LeetoCode地址: . - 力扣(LeetCode)

题目理解

可以通过归纳法证明出一棵树的最小高度树可以通过从最外面度为1的叶子节点一层一层向内遍历得到,可以使用一种称为 **中心缩减法**(或称为 **剥洋葱法**)的方法。我们将逐步解释这个方法,并证明其正确性。

### 定义和问题陈述
- **树**:无环连通图。
- **树的高度**:从根节点到任意叶子节点的最长路径。
- **最小高度树**:使树的高度最小的树。对于给定的无向树,可能存在多个根节点,使得树的高度最小。

### 中心缩减法(剥洋葱法)

这个方法的核心思想是逐步移除树的叶子节点(度为1的节点),直到剩下最后一个或两个节点,这些节点就是树的最小高度树的根。

### 证明

#### 步骤和直观理解

1. **初始阶段**:
   - 考虑一棵树 \( T \) 和它的所有叶子节点集合 \( L \)。

2. **移除叶子节点**:
   - 移除所有的叶子节点 \( L \) 及其连接的边,形成一个新的子树 \( T' \)。
   - 移除叶子节点后,新的叶子节点是那些在 \( T \) 中与 \( L \) 相邻的节点。

3. **重复过程**:
   - 对于新的子树 \( T' \),重复上述步骤,继续移除当前的叶子节点。
   - 这一过程持续进行,直到剩下一个或两个节点为止。

#### 数学证明

- **基础情况**:单节点树显然是其自身的最小高度树。
- **归纳步骤**:
  - 设在移除了一层叶子节点后,新的子树 \( T' \) 的高度减少1。
  - 继续移除,直到树的高度不能再减少,这时剩下的一个或两个节点即为树的中心节点。

#### 详细证明

1. **叶子节点的性质**:
   - 叶子节点位于树的最外层,其高度为最大高度。
   - 移除叶子节点不会影响其他节点的连接性,因为树是无环连通图,移除叶子节点后剩下的子图依然是一棵树。

2. **递归缩减的效果**:
   - 移除一层叶子节点后,新的子树 \( T' \) 的所有节点的高度都减少1。
   - 如果继续移除叶子节点,最终会缩减到树的中心部分。

3. **树的中心性质**:
   - 对于树的最小高度树,其根节点到所有叶子节点的路径是最短的。
   - 逐层移除叶子节点的方法保证了树的中心在最后一步被识别出来,因为剩下的一个或两个节点即为树的中心。

### 结论

通过逐层移除树的叶子节点,最终剩下的一个或两个节点即为树的中心节点,这些节点就是形成最小高度树的根节点。因此,树的最小高度树可以通过从最外面度为1的叶子节点一层一层向内遍历得到。

写法1(BFS)

时间复杂度: O(n)

空间复杂度: O(n)

每一层‘洋葱皮’其实就是树的叶子结点集合,而每一层都是潜在的答案,所以我们要将其缓存起来,直到最后没有其他更内部的洋葱皮!。

class Solution {public List<Integer> findMinHeightTrees(int n, int[][] edges) {List<Integer> res = new ArrayList<>();if (n == 1) {res.add(0);return res;}int[] degree = new int[n];ArrayList[] adj = new ArrayList[n];for (int i = 0; i < n; i++) {adj[i] = new ArrayList<Integer>();}for (int i = 0; i < edges.length; i++) {int x = edges[i][0], y = edges[i][1];degree[x]++;degree[y]++;adj[x].add(y);adj[y].add(x);}Deque<Integer> queue = new ArrayDeque<>();for (int i = 0; i < n; i++) {if (degree[i] == 1) {queue.offer(i);}}int remainCnt = n;while (remainCnt > 2) {int size = queue.size();remainCnt -= size;for (int i = 0; i < size; i++) {int u = queue.poll();List<Integer> nodes = adj[u];for (Integer next : nodes) {degree[next]--;if (degree[next] == 1) {queue.offer(next);}}}}while (!queue.isEmpty()) {res.add(queue.poll());}return res;}
}

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

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

相关文章

StarRocks分区表历史数据删除与管理

一、背景介绍 在使用 StarRocks 时&#xff0c;可能会遇到需要删除大批量数据的情况。然而&#xff0c;StarRocks 对 DELETE 操作的支持并不理想&#xff0c;主要存在以下问题&#xff1a; 不建议执行高频的 DELETE 操作&#xff1a;删除的数据会标记为“Deleted”&#xff0…

判断一组数据哪些是素数,并统计一个数组中元素的出现频率

import java.util.HashMap; import java.util.Map; public class Test_A26 {//判断一个数是不是素数public static boolean isPrime(int num){if(num<1){return false;}for(int i2;i<Math.sqrt(num);i){if(num%i0){return false;}}return true;}//统计数组中出现的频率 p…

python安装目录文件说明----Dlls文件夹

在Python的安装目录下&#xff0c;通常会有一个DLLs文件夹&#xff0c;它是Python标准库的一部分。这个文件夹包含了一些动态链接库&#xff08;Dynamic Link Libraries&#xff0c;DLL&#xff09;&#xff0c;这些库提供了Python解释器和标准库的一些关键功能。以下是对这个文…

模拟自动滚动并展开所有评论列表以及回复内容(如:抖音、b站等平台)

由于各大视频平台的回复内容排序不都是按照时间顺序&#xff0c;而且想看最新的评论回复讨论内容还需逐个点击展开&#xff0c;真的很蛋疼&#xff0c;尤其是热评很多的情况&#xff0c;还需要多次点击展开&#xff0c;太麻烦&#xff01; 于是写了一个自动化展开所有评论回复…

Kaggle比赛:成人人口收入分类

拿到数据首先查看数据信息和描述 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desk…

嵌入式技术学习——c51——串口

一、串口介绍。 串口是一个 通讯接口。成本低&#xff0c;容易使用&#xff0c;通信线路简单&#xff0c;可实现两个设备的相互通信 单片机的串口可以实现单片机于单片机&#xff0c;单片机与电脑&#xff0c;单片机与其他模块相互通信。 51单片机内部自带UART&#xff0c;通…

一句话的哲学 (上集)

一&#xff0c;成全别人&#xff0c;委屈自己&#xff0c;轻软和不好意思就是杀死自己的最好的方式。 养一群吸血鬼&#xff0c;成全了别人&#xff0c;委屈了自己&#xff0c;最后呢&#xff0c;还被别人当成了傻瓜。 二 背后议论你的狗什么品种都有人活在世上&#xff0c;总会…

Flutter图像编辑器应用:创造生动美丽的照片体验

介绍 引言 想象一下&#xff0c;在一个阳光明媚的下午&#xff0c;与家人或朋友漫步在风景如画的街道上。拿出手机&#xff0c;迫不及待地捕捉这一刻的美好&#xff0c;按下快门&#xff0c;留下了一张充满回忆的照片。 然而&#xff0c;回到家后发现照片的亮度有些偏暗&…

【完结】无代码网页爬虫软件——八爪鱼采集器入门基础教程

《八爪鱼采集器入门基础教程》大纲如下&#xff1a; 课程所提软件&#xff0c;八爪鱼采集器下载&#xff1a; 1.软件分享[耶]八爪鱼&#xff0c;爬取了几百条网站上的公开数据&#xff0c;不用学代码真的很方便。[得意]2.发现了一个很棒的软件&#xff0c;?不用学python也可…

周跳的探测及修复

前言&#xff1a; 本章节代码均在Gitee中开源&#xff1a; 导航工程: 导航工程及其有关的所有项目 - Gitee.comhttps://gitee.com/Ehundred/navigation-engineering/tree/master/%E5%8D%AB%E6%98%9F%E5%AF%BC%E8%88%AA%E5%8E%9F%E7%90%86/%E5%91%A8%E8%B7%B3%E6%8E%A2%E6%B5%…

工作学习记录

代码块含义大体解析&#xff1a; 1. QSqlDatabase mCurDatabase; QString driverName mCurDatabase.driverName(); 返回连接的驱动名。 如QSQLITE 2.sqlite数据库中查询是否存在表tableName select * from sqlite_master where type table and nametableName 3. QSqlQ…

关于到ORCL数据库实例的连接,哪个语句是正确的?

您的hq.us.example.com主机的tnsnames.ora中有以下条目。 ORCL (DESCRIPTION (ADDRESS_LIST (ADDRESS (PROTOCOL TCP)(HOST hq.us.example.com)(PORT 1521)) ) CONNECT_DATA (SERVICE_NAME ORCL.us.example.com) ) 你发出以下命令: Sqlplus H…

软件测试--性能测试

1.性能 时间&#xff1a;响应时间 资源&#xff1a;资源的消耗情况 2.性能测试 使用自动化工具&#xff0c;模拟不同场景&#xff0c;对软件各项性能指标进行测试和评估的过程 3.为什么做性能测试 1.评估系统能能力 2.寻找性能瓶颈&#xff0c;优化性能 4.什么时候做性…

深入解析Spring Boot的常用注解和组件(下)

在上一篇文章中&#xff0c;我们介绍了Spring Boot的常用注解及其应用场景。本文将继续探讨Spring Boot的常用组件及其在实际开发中的应用。## 2. Spring Boot的常用组件### 2.1 Spring Boot StarterSpring Boot Starter是Spring Boot项目的一部分&#xff0c;它提供了一组方便…

什么是Vue开发技术

概述 Vue.js 是一个用于构建用户界面的渐进式框架&#xff0c;它设计得非常灵活&#xff0c;可以轻松地被集成到任何项目中。 vue是视图的发音&#xff0c;其目的是帮助开发者易于上手&#xff0c;提供强大的功能构建复杂的应用程序 示例 以下是vue基本的语法概述 声明式渲…

探索C嘎嘎的奇妙世界:第一关---命名空间

1:命名空间 C就是延续C语言的一些不足进行改进和优化,也是一门值得我们深入探索和钻研的编程语言。它就像一个充满宝藏的宝库&#xff0c;等待着我们去发掘其中的奥秘和惊喜.那么就让我们来打开C的大门,进行探索吧!!! 首先,C要在C语言优化的第一个问题:命名冲突, 那么C语言是具…

探索未来工作新伙伴:机器人流程自动化(RPA)揭秘

想象一下&#xff0c;如果你的日常工作中那些繁琐、重复的任务&#xff0c;比如数据录入、文件整理、邮件发送等&#xff0c;都能自动完成&#xff0c;你将拥有更多时间专注于真正需要创造力和智慧的工作&#xff0c;是不是听起来就像拥有了一个私人助理&#xff1f;这并不是遥…

VUE3版本新特性

VUE3版本新特性 VUE3和VUE2的区别路由的使用vite安装项目新特性使用 1.VUE3和VUE2的区别 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece 于 2022 年 2 月 7 日星期一成为新的默认版本! Vue3性能更高,初次渲染快55%, 更新渲染快133% 。…

推荐 3 款小巧的文件压缩、投屏和快速启动软件,请收藏,避免找不到

Maya Maya是一款由博主25H开发的体积小巧、简单易用的快速启动工具。它的操作逻辑和界面设计几乎复刻了Rolan早期版本&#xff0c;功能上与Rolan几乎别无二致。Maya支持多文件拖拽添加启动、快捷键呼出、自动多列显示等功能。此外&#xff0c;Maya还具备lnk文件解析功能。 May…

多目标粒子群算法(MOPSO):原理讲解与代码实现 Matlab代码免费获取

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 粒子群算法 多目标粒子群算法 一、外部档案…