2024.3.17力扣每日一题——最小高度树

2024.3.17

      • 题目来源
      • 我的题解
        • 方法一 深度优先遍历
        • 方法二 广度优先遍历
        • 方法三 拓扑排序

题目来源

力扣每日一题;题序:310

我的题解

方法一 深度优先遍历

从每一个节点开始进行深度优先遍历并计算以该节点为根节点的树的深度,使用哈希表存储对应深度有哪些节点,最后取出key最小对应的value的作为结果。超时。

时间复杂度:O( n 2 n^2 n2)
空间复杂度:O(n)

TreeMap<Integer,Set<Integer>> map=new TreeMap<>();
public List<Integer> findMinHeightTrees(int n, int[][] edges) {List<Integer>[] g=createTree(n,edges);for(int i=0;i<n;i++){int minDeep=dfs(g,i,i,-1,1);System.out.println(minDeep);Set<Integer> l=map.getOrDefault(minDeep,new HashSet<>());l.add(i);map.put(minDeep,l);}return new ArrayList<>(map.firstEntry().getValue());
}
public List<Integer>[] createTree(int n,int[][] edges){List<Integer>[] g=new ArrayList[n];for(int i=0;i<n;i++){g[i]=new ArrayList<>();}for(int[] t:edges){int from = t[0];int to = t[1];g[from].add(to);g[to].add(from);}return g;
}
public int  dfs(List<Integer>[] g,int root,int cur,int pre,int deepth){int minDeep=0;for(int next:g[cur]){if(next!=pre){int t=dfs(g,root,next,cur,deepth+1);minDeep=Math.max(minDeep,t);}}return minDeep+1;
}

由于一定是树,所以具有最小深度的根节点只有可能最多两个节点作为个根时的深度是相同的。所以,可以求该图中最长的直径,中间节点就是需要求的根节点。所以,不用对所有节点都进行深度优先遍历,只需要遍历两个节点就行了。
时间复杂度:O(n)
空间复杂度:O(n)

//优化版本
TreeMap<Integer,Set<Integer>> map=new TreeMap<>();
List<Integer> path=new ArrayList<>();
int deep=0;
public List<Integer> findMinHeightTrees(int n, int[][] edges) {List<Integer>[] g=createTree(n,edges);//优化的地方List<Integer> p=new ArrayList<>();int x=0;p.add(x);dfs(g,x,-1,1,p);p=new ArrayList<>();int y=path.get(path.size()-1);p.add(y);dfs(g,y,-1,1,p);int sz=path.size();if(sz%2==0){return path.subList(sz/2-1,sz/2+1);}else{return path.subList(sz/2,sz/2+1);}
}
public List<Integer>[] createTree(int n,int[][] edges){List<Integer>[] g=new ArrayList[n];for(int i=0;i<n;i++){g[i]=new ArrayList<>();}for(int[] t:edges){int from = t[0];int to = t[1];g[from].add(to);g[to].add(from);}return g;
}
public void  dfs(List<Integer>[] g,int cur,int pre,int deepth,List<Integer> p){if(deepth>deep){path=new ArrayList<>(p);deep=deepth;}for(int next:g[cur]) {if (next != pre) {p.add(next);dfs(g, next, cur, deepth + 1, p);p.remove(p.size() - 1);}}
}
方法二 广度优先遍历

在方法一的优化版本基础上,也可以采用广度优先遍历来求最长直径。

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

TreeMap<Integer,Set<Integer>> map=new TreeMap<>();
List<Integer> path=new ArrayList<>();
int deep=0;
public List<Integer> findMinHeightTrees(int n, int[][] edges) {List<Integer>[] g=createTree(n,edges);//变化之处在于采用广度优先遍历求最长直径int x=0;bfs(g,x);int y=path.get(path.size()-1);bfs(g,y);int sz=path.size();if(sz%2==0){return path.subList(sz/2-1,sz/2+1);}else{return path.subList(sz/2,sz/2+1);}
}
public List<Integer>[] createTree(int n,int[][] edges){List<Integer>[] g=new ArrayList[n];for(int i=0;i<n;i++){g[i]=new ArrayList<>();}for(int[] t:edges){int from = t[0];int to = t[1];g[from].add(to);g[to].add(from);}return g;
}
public void bfs(List<Integer>[] g,int cur){Queue<Integer> queue=new LinkedList<>();queue.offer(cur);int[] parent=new int[g.length];//记录路径parent[cur]=-1;boolean[] visited=new boolean[g.length];visited[cur]=true;//最后一层的节点int end=cur;while(!queue.isEmpty()){int sz=queue.size();for (int i = 0; i < sz; i++) {int t=queue.poll();boolean f=false;for(int next:g[t]){if(visited[next])continue;parent[next]=t;visited[next]=true;queue.offer(next);f=true;}if(!f)end=t;}}path.clear();while(end!=-1){path.add(0,end);end=parent[end];}
}
方法三 拓扑排序

最小深度也可以看做是一直删除叶子节点,最后剩下的一个或者两个节点就是满足条件的节点。这种每次删除叶子节点的操作实质就是拓扑排序。

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

public List<Integer> findMinHeightTrees(int n, int[][] edges) {//注意:使用拓扑排序需要将只有一个节点的情况单独考虑if(n==1)return Arrays.asList(0);int[] tp=new int[n];List<Integer>[] g=createTree(n,edges,tp);Queue<Integer> queue=new LinkedList<>();for(int i=0;i<n;i++){if(tp[i]==1)queue.offer(i);}return tpFunc(g,tp,n,queue);
}
public List<Integer>[] createTree(int n,int[][] edges,int[] tp){List<Integer>[] g=new ArrayList[n];for(int i=0;i<n;i++){g[i]=new ArrayList<>();}for(int[] t:edges){int from = t[0];int to = t[1];g[from].add(to);g[to].add(from);tp[from]++;tp[to]++;}return g;
}
public List<Integer> tpFunc(List<Integer>[] g,int[] tp,int remain,Queue<Integer> queue){List<Integer> res=new ArrayList<>();while(remain>2){int sz=queue.size();remain-=sz;for(int i=0;i<sz;i++){int t=queue.poll();for(int next:g[t]){tp[t]--;tp[next]--;if(tp[next]==1)queue.offer(next);}}}while(!queue.isEmpty()){res.add(queue.poll());}return res;
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

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

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

相关文章

团体程序设计天梯赛-练习集 01

天梯赛题解合集 团体程序设计天梯赛-练习集 (L1-001 - L1-012) 团体程序设计天梯赛-练习集 (L1-013 - L1-024) 团体程序设计天梯赛-练习集 (L1-025 - L1-036) 团体程序设计天梯赛-练习集 (L1-037 - L1-048) L1-001 Hello World 输出题 样例 输入 输出 Hello World!思…

爬虫之数据神器5---Peewee数据库关系映射实践

前言&#xff1a; 继续上一章&#xff1a;爬虫之数据神器4---Peewee事务管理和连接池用法-CSDN博客 本章主要就是对peewee的实战进行一些案例的讲解&#xff01; 正文&#xff1a; 1.模型数据操作 1.1 案例:建立学生和课程模型,实现基本的CRUD 我们先创建Student和Course两…

【LAMMPS学习】七、加速性能(5)加速器包比较

7. 加速性能 7.1.基准测试 7.2.测试性能 7.3.通用技巧 7.4.加速器包 7.5.加速器包比较 接下来将比较和对比各种加速器选项&#xff0c;因为有多种方法可以执行 OpenMP 线程、在 GPU 上运行、优化 CPU 上的向量单元以及在英特尔至强融核&#xff08;协&#xff09;处理器上…

爬虫之数据神器4---Peewee事务管理和连接池用法

前言&#xff1a; 继续上一章节&#xff1a;爬虫之数据神器3---Peewee模型定义详解-CSDN博客 事务管理和连接池的重要性 事务管理和连接池是在开发和维护数据库应用程序时非常重要的概念和技术。 事务管理&#xff1a;事务是指作为一个逻辑单元执行的一系列数据库操作。事务具…

图像处理ASIC设计方法 笔记13 图像旋转ASIC的输入输出电路

文章目录 1 DPRAM:双端口 RAM2 IDT Integrated Device Technology, Inc. 公司介绍3 IDT70T633S10DDI4 TMS320C64145 旋转ASIC的输入输出框图图像旋转ASIC的输入输出电路案例用到的芯片相关介绍如下。 1 DPRAM:双端口 RAM DPRAM 的特点是可以通过两个端口同时访问,具有两套完全…

数据结构入门系列-栈的结构及栈的实现

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 栈 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一段进行插入和删除元素操作&#xff0c;进行数据输入和删除操作的一端称为栈顶&#xff0c;另…

如何在TestNG中获取运行时的测试用例细节?

这篇文章将讨论如何在运行时获取测试用例的细节。我们可能在不同的场景中需要这些信息&#xff0c;比如创建定制的报告或者开发一个实时跟踪系统来监视测试用例的进度。 让我们从使用TestNG运行测试套件开始开始。然后&#xff0c;我们将尝试检索每个测试用例的细节&#xff0…

【授时防火墙】GPS北斗卫星授时信号安全防护装置系统

【授时防火墙】GPS北斗卫星授时信号安全防护装置系统 【授时防火墙】GPS北斗卫星授时信号安全防护装置系统 1、装置概述 卫星信号安全防护装置&#xff08;以下简称“防护装置”&#xff09;是一款专门针对卫星导航授时安全的设备。该设备能接收 BD 系统和 GPS 系统卫星信号&am…

InternLM2-Chat-1.8B 模型测试

在interStudio进行InternLM2-Chat-1.8B模型访问&#xff0c;进入开发机后 配置基础环境 新建conda环境并且进入 conda create -n demo python3.10 -y conda activate demo 下载pytorch等相关包 conda install pytorch2.0.1 torchvision0.15.2 torchaudio2.0.2 pytorch-cuda11.…

ChernoCPP 2

视频链接&#xff1a;【62】【Cherno C】【中字】C的线程_哔哩哔哩_bilibili 参考文章&#xff1a;TheChernoCppTutorial_the cherno-CSDN博客 Cherno的C教学视频笔记&#xff08;已完结&#xff09; - 知乎 (zhihu.com) C 的线程 #include<iostream> #include<th…

四、MySQL读写分离之MyCAT

一、读写分离概述 1、什么是读写分离&#xff1a; 读写分离&#xff1a;就是将读写操作分发到不同的服务器&#xff0c;读操作分发到对应的服务器 &#xff08;slave&#xff09;&#xff0c;写操作分发到对应的服务器&#xff08;master&#xff09; ① M-S (主从) 架构下&…

Java设计模式:外观模式之优雅门面(九)

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在软件工程中&#xff0c;设计模式是解决常见设计问题的经验总结&#xff0c;它为开发者提供了一种通用的、可复用的解决方案。外…

书生浦语训练营2期-第二节课笔记作业

目录 一、前置准备 1.1 电脑操作系统&#xff1a;windows 11 1.2 前置服务安装&#xff08;避免访问127.0.0.1被拒绝&#xff09; 1.2.1 iis安装并重启 1.2.2 openssh安装 1.2.3 openssh服务更改为自动模式 1.2.4 书生浦语平台 ssh配置 1.3 补充&#xff08;前置服务ok…

Thread的基本用法

目录 正文&#xff1a; 1.线程创建 2.线程休眠 3.获取线程实例 4.线程中断 5.线程等待join() 总结&#xff1a; 正文&#xff1a; 1.线程创建 线程创建是多线程编程的第一步&#xff0c;它涉及到创建一个可以并行执行的新线程。在Java中&#xff0c;有几种不同的方法可…

【Laravel】08 RESTful风格

【Laravel】08 视图模板动态渲染数据 1. RESTful风格 1. RESTful风格 (base) ➜ example-app php artisan make:model Blog -mc Model created successfully. Created Migration: 2024_04_01_143040_create_blogs_table Controller created successfully.(base) ➜ example-…

深入理解微信小程序的自定义组件模型

微信小程序作为一个独立的应用开发平台,提供了丰富的组件库供开发者使用。但在某些复杂的业务场景下,我们需要根据自身的需求来定制化组件。小程序为我们提供了自定义组件的能力,让我们可以更灵活地构建应用界面。 如果对微信小程序自定义组件还不太清楚的&#xff0c;请参考 …

简述JMeter实现分布式并发及操作

为什么要分布式并发&#xff1f; JMeter性能实践过程中&#xff0c;一旦进行高并发操作时就会出现以下尴尬场景&#xff0c;JMeter客户端卡死、请求错误或是超时等&#xff0c;导致很难得出准确的性能测试结论。 目前知道的有两个方法可以解决JMeter支撑高并发&#xff1a; …

pta 1036 跟奥巴马一起编程

1036 跟奥巴马一起编程 分数 15 全屏浏览 切换布局 作者 CHEN, Yue 单位 浙江大学 美国总统奥巴马不仅呼吁所有人都学习编程&#xff0c;甚至以身作则编写代码&#xff0c;成为美国历史上首位编写计算机代码的总统。2014 年底&#xff0c;为庆祝“计算机科学教育周”正式启…

阿里 对象存储OSS 云存储服务

1.简介 对象存储服务(Object Storage Service ,OSS) 是一种 海量、安全、低成本、高可靠的云存储服务&#xff0c;适合存放任意类型的文件。容量和处理能力弹性扩展&#xff0c;多种存储类型供选择&#xff0c;全面优化存储成本。 2.如何使用。参考文档 看文档&#xff0c;说的…

【python从入门到精通】-- 第四战:语句汇总

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…