【二叉树 C++DFS】2458. 移除子树后的二叉树高度

本文涉及知识点

二叉树 C++DFS

LeetCode 2458. 移除子树后的二叉树高度

给你一棵 二叉树 的根节点 root ,树中有 n 个节点。每个节点都可以被分配一个从 1 到 n 且互不相同的值。另给你一个长度为 m 的数组 queries 。
你必须在树上执行 m 个 独立 的查询,其中第 i 个查询你需要执行以下操作:
从树中 移除 以 queries[i] 的值作为根节点的子树。题目所用测试用例保证 queries[i] 不 等于根节点的值。
返回一个长度为 m 的数组 answer ,其中 answer[i] 是执行第 i 个查询后树的高度。
注意:
查询之间是独立的,所以在每个查询执行后,树会回到其 初始 状态。
树的高度是从根到树中某个节点的 最长简单路径中的边数 。
示例 1:
输入:root = [1,3,4,2,null,6,5,null,null,null,null,null,7], queries = [4]
输出:[2]
解释:上图展示了从树中移除以 4 为根节点的子树。
树的高度是 2(路径为 1 -> 3 -> 2)。
示例 2:
输入:root = [5,8,9,2,1,3,7,4,6], queries = [3,2,4,8]
输出:[3,2,3,2]
解释:执行下述查询:

  • 移除以 3 为根节点的子树。树的高度变为 3(路径为 5 -> 8 -> 2 -> 4)。
  • 移除以 2 为根节点的子树。树的高度变为 2(路径为 5 -> 8 -> 1)。
  • 移除以 4 为根节点的子树。树的高度变为 3(路径为 5 -> 8 -> 2 -> 6)。
  • 移除以 8 为根节点的子树。树的高度变为 2(路径为 5 -> 9 -> 3)。
    提示:
    树中节点的数目是 n
    2 <= n <= 105
    1 <= Node.val <= n
    树中的所有值 互不相同
    m == queries.length
    1 <= m <= min(n, 104)
    1 <= queries[i] <= n
    queries[i] != root.val

深度优先搜索(错误)

DFS的参数:TreeNode* root ,int height 。height是当前节点到根节点的最短距离。
DFS的返回值:当前子树的高度。
m_vRet[i] 记录删除值为i的子树后,高度减少多少。
DFS:过程。
记录各子树的高度。
如果没有子树,返回。
令child1是最高的子树,child2是次高的子树。
m_vRet[child1] = child1的高度-child2的高度。
如果child2不存在,可以假定它的高度为-1。
对个查询的值,整棵树的高度-m_vRet[que]
错误原因: 只有删除同层次(leve)节点高度最高的子树时,高度才会发生变化。不是兄弟节点的最高,次高;而是整个层次的最高次高。

深度优先搜索(更正)

DFS的参数:TreeNode* cur,int leve
DFS返回值:m_leve2[cur->value]
DFS:过程
m_leve[cur]记录,cur的层次,根节点是0。
m_leve2[cur]记录,cur子树的层次数量。 叶子节点为1。
分如下几步:
int iHeight = DFS(root,0);
leveToLeve2 记录各层次的leve2
对leveToLeve2[i]按降序排序
计算各查询的sub:
auto& v = leveToLeve2[m_leve[que]];
如果不是当前层次的最大leve2,则sub为0。
如果当前层次只有一个节点,sub = v[0]
否则 sub = v[1]
当前查询的值就是:iHeight-1 - sub。
时间复杂度:O(nlogn) 理论上瓶颈在排序,实际上在DFS。力扣上的DFS非常花时间。

代码

核心代码

#define MaxValue (100'000)
class Solution {
public:vector<int> treeQueries(TreeNode* root, vector<int>& queries) {int iHeight = DFS(root,0);vector<int> leveToLeve2[MaxValue + 1];for (int i = 1; i <= MaxValue; i++) {leveToLeve2[m_leve[i]].emplace_back(m_leve2[i]);}for (int i = 0; i < MaxValue; i++) {sort(leveToLeve2[i].begin(), leveToLeve2[i].end(),greater<>());}vector<int> ret;for (const auto& que : queries) {int sub = 0;auto& v = leveToLeve2[m_leve[que]];if (m_leve2[que] == v[0]) {sub = (1 == v.size()) ? v[0] : (v[0] - v[1]);}ret.emplace_back(iHeight-1 - sub);}return ret;}int DFS(TreeNode* cur,int leve) {if (nullptr == cur) { return 0; }m_leve[cur->val] = leve;const int i1 = DFS(cur->left,leve+1);const int i2 = DFS(cur->right,leve+1);		return m_leve2[cur->val] = max(i1, i2) + 1;}int m_leve[MaxValue + 1] = { 0 };int m_leve2[MaxValue + 1] = { 0 };};

单元测试

template<class T1, class T2>
void AssertEx(const T1& t1, const T2& t2)
{Assert::AreEqual(t1, t2);
}template<class T>
void AssertEx(const vector<T>& v1, const vector<T>& v2)
{Assert::AreEqual(v1.size(), v2.size());for (int i = 0; i < v1.size(); i++){Assert::AreEqual(v1[i], v2[i]);}
}template<class T>
void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
{sort(vv1.begin(), vv1.end());sort(vv2.begin(), vv2.end());Assert::AreEqual(vv1.size(), vv2.size());for (int i = 0; i < vv1.size(); i++){AssertEx(vv1[i], vv2[i]);}
}namespace UnitTest
{vector<int> nums, queries;const int null = 100'000;TEST_CLASS(UnitTest){public:TEST_METHOD(TestMethod00){nums = { 1, 3, 4, 2, null, 6, 5, null, null, null, null, null, 7 }, queries = { 4 };auto root = NTree::Init(nums,null);auto res = Solution().treeQueries(root, queries);AssertEx(vector<int>{2}, res);}TEST_METHOD(TestMethod01){nums = { 5,8,9,2,1,3,7,4,6 }, queries = { 3,2,4,8 };auto root = NTree::Init(nums, null);auto res = Solution().treeQueries(root, queries);AssertEx(vector<int>{3, 2, 3, 2}, res);}};
}

求第k小函数优化

nth_element(a,a+k,a+n);
功能:函数只是把下标为k的元素放在了正确位置,对其它元素并没有排序当然k左边元素都小于等于它,右边元素都大于等于它,所以可以利用这个函数快速定位某个元素。
理论上可以把时间复杂度降到:O(n) 实际上稍稍提高速度。

class Solution {
public:vector<int> treeQueries(TreeNode* root, vector<int>& queries) {int iHeight = DFS(root,0);vector<int> leveToLeve2[MaxValue + 1];for (int i = 1; i <= MaxValue; i++) {leveToLeve2[m_leve[i]].emplace_back(m_leve2[i]);}for (int i = 0; i < MaxValue; i++) {if(leveToLeve2[i].size() >= 2 )nth_element(leveToLeve2[i].begin(), leveToLeve2[i].end()-2,leveToLeve2[i].end());}vector<int> ret;for (const auto& que : queries) {int sub = 0;auto& v = leveToLeve2[m_leve[que]];if (m_leve2[que] == v.back()) {sub = (1 == v.size()) ? v.back() : (v.back() - v[v.size()-2]);}ret.emplace_back(iHeight-1 - sub);}return ret;}int DFS(TreeNode* cur,int leve) {if (nullptr == cur) { return 0; }m_leve[cur->val] = leve;const int i1 = DFS(cur->left,leve+1);const int i2 = DFS(cur->right,leve+1);		return m_leve2[cur->val] = max(i1, i2) + 1;}int m_leve[MaxValue + 1] = { 0 };int m_leve2[MaxValue + 1] = { 0 };};

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关推荐

我想对大家说的话
《喜缺全书算法册》以原理、正确性证明、总结为主。
按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

深入理解计算机系统 CSAPP 家庭作业11.8

回收子进程是书本537页的内容 在tiny.c文件加以下代码,记得重新编译哦 书中提到CGI是在动态内容中的,所以题目的意思应该是在动态内容里面回收 void handler1(int sig) {int olderrno errno;while (waitpid(-1,NULL,0)>0){Sio_puts("Handler reaped child\n");…

Scrapy 爬取旅游景点相关数据(四)

本节内容主要为&#xff1a; &#xff08;1&#xff09;创建数据库 &#xff08;2&#xff09;创建数据库表 &#xff08;3&#xff09;爬取数据进MYSQL库 1 新建数据库 使用MYSQL数据库存储数据&#xff0c;创建一个新的数据库 create database scrapy_demo;2 新建数据表 CR…

开发者的AI革命:我们仍在敲代码,AI为何没有取代我们的工作?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【区块链+绿色低碳】雄韬智慧锂电储能管理系统 | FISCO BCOS应用案例

雄韬智慧锂电储能管理系统&#xff08;Energy Management System&#xff0c;以下简称 EMS&#xff09;是雄韬集团响应国家实现新型电力 系统建设&#xff0c;助力“碳达峰、碳中和”目标而自主开发的创新智慧锂电储能系统。 系统采用了 FISCO BCOS 联盟链&#xff0c;融合了物…

放大电路总结

补充: 只有直流移动时才有Rbe动态等效电阻 从RsUs看进去,实际上不管接了什么东西都能够看成是一个Ri(输入电阻) Ri Ui/Ii Rb//Rbe Ui/Us Ri/(RiRs) Aus (Uo/Ui)*(Ui/Us) Au *Ri/(RiRs) 当前面是一个电压源的信号 我们就需要输入电阻更大 Ro--->输出电阻--->将…

Mybatis(四)特殊SQL的查询:模糊查询、批量删除、动态设置表明、添加功能获取自增的主键

实体类&#xff1a; 数据库&#xff1a; 1、模糊查询 方案一&#xff1a; 不适用#{ }&#xff0c;’%?%‘ 问号是属于字符串的一部分 不会被解析成占位符&#xff0c;会被当作是我们字符串的一部分来解析&#xff0c;所以我们执行的语句中找不到占位符&#xff0c;但是我们却…

帕金森病(PD)诊断:三种基于语音的深度学习方法

帕金森病&#xff08;Parkinson’s disease, PD&#xff09;是世界上第二大流行的神经退行性疾病&#xff0c;全球影响着超过1000万人&#xff0c;仅次于阿尔茨海默症。人们通常在65岁左右被诊断出患有此病。PD的一些症状包括震颤、肌肉僵硬和运动迟缓。这些症状往往出现在较晚…

跟《经济学人》学英文:2024年07月20日这期 Japan’s strength produces a weak yen

Japan’s strength produces a weak yen Currency meddling will prove futile 货币干预将被证明是徒劳的 meddling&#xff1a;干涉&#xff1b;摸弄&#xff1b;&#xff08;meddle的现在分词形式&#xff09; futile&#xff1a; 美 [ˈfjuːtl] 无效的&#xff1b;徒劳…

RKNN3588——YOLOv10的PT模型转RKNN模型

一&#xff1a;PT转ONNX 修改yolov10的源码 1. 修改head.py文件&#xff0c;在lass v10Detect(Detect)中的forward添加 # 导出onnx增加y []for i in range(self.nl):t1 self.one2one_cv2[i](x[i])t2 self.one2one_cv3[i](x[i])y.append(t1)y.append(t2)return y# 导出onnx…

(精校版)高校大数据实验室建设解决方案

在当今数据驱动的时代&#xff0c;大数据已成为推动社会发展的核心动力。高校作为培养未来社会精英和科技创新人才的摇篮&#xff0c;迫切需要建设大数据实验室&#xff0c;以应对日益增长的大数据人才需求和科学研究挑战。大数据实验室不仅能够提供先进的教学资源和实践平台&a…

mysql面试(七)

前言 本章节列出了mysql在增删改查的时候&#xff0c;分别会涉及到哪些锁类型&#xff0c;又是如何交互的。 这个章节也是mysql面试基础系列的最后一章&#xff0c;后面准备更新redis数据类型和分布式锁相关问题。如果各位看官有什么问题的话&#xff0c;可以留言。 锁 之前…

leetocde662. 二叉树最大宽度,面试必刷题,思路清晰,分点解析,附代码详解带你完全弄懂

leetocde662. 二叉树最大宽度 做此题之前可以先做一下二叉树的层序遍历。具体题目如下&#xff1a; leetcode102二叉树的层序遍历 我也写过题解&#xff0c;可以先看看学习一下&#xff0c;如果会做层序遍历了&#xff0c;那么这题相对来说会简单很多。 具体题目 给你一棵…

Vue3+Element Plus 实现table表格中input的验证

实现效果 html部分 <template><div class"table"><el-form ref"tableFormRef" :model"form"><el-table :data"form.detailList"><el-table-column type"selection" width"55" align&…

Wonder3D 论文学习

论文链接&#xff1a;https://arxiv.org/abs/2310.15008 代码链接&#xff1a;https://github.com/xxlong0/Wonder3D 解决了什么问题&#xff1f; 随着扩散模型的提出&#xff0c;3D 生成领域取得了长足进步。从单张图片重建出 3D 几何是计算机图形学和 3D 视觉的基础任务&am…

【限免】16PAM、16PSK、16QAM、16CQAM星座图及误码率【附MATLAB代码】

​微信公众号&#xff1a;智能电磁频谱算法 QQ交流群&#xff1a;949444104 主要内容 MATLAB代码 % Parameters M 16; N 4; % Number of circles for CQAM SNR_dB 0:2:25; % Extended SNR range to reach higher values num_symbols 1e5; % Total number of symbols for s…

Linux学习笔记 --- 环境配置

在成功装载Ubuntu系统后我们需要设置其与windows系统的共享文件夹&#xff0c;按照以下步骤操作 设置完共享文件夹后在终端执行以下命令查看是否成功设置 此时下方出现设置的共享文件夹名称则为成功设置 如果未显示可以尝试进行重新安装VMware tools&#xff0c;步骤如下&…

git等常用工具以及cmake

一、将git中的代码克隆进电脑以及常用工具介绍 1.安装git 首先需要安装git sudo apt install git 注意一定要加--recursive&#xff0c;因为文件中有很多“引用文件“&#xff0c;即第三方文件&#xff08;库&#xff09;&#xff0c;加入该选项会将文件中包含的子模…

系统架构设计师②:操作系统

系统架构设计师②&#xff1a;操作系统 操作系统作用 ①管理系统的硬件、软件、数据资源 ②控制程序运行 ③人机之间的接口 ④应用软件与硬件之间的接口 进程管理 进程是程序在一个数据集合上运行的过程&#xff0c;它是系统进行资源分配和调度的一个独立单位。它由程序块、…

FastAPI(七十八)实战开发《在线课程学习系统》接口开发-- 评论

源码见&#xff1a;"fastapi_study_road-learning_system_online_courses: fastapi框架实战之--在线课程学习系统" 梳理下思路 1.判断是否登录 2.课程是否存在 3.如果是回复&#xff0c;查看回复是否存在 4.是否有权限 5.发起评论 首先新增pydantic模型 class Cour…

如何系统的学习C++和自动驾驶算法

给大家分享一下我的学习C和自动驾驶算法视频&#xff0c;收藏订阅都很高。打开下面的链接&#xff0c;就可以看到所有的合集了&#xff0c;订阅一下&#xff0c;下次就能找到了。 【C面试100问】第七十四问&#xff1a;STL中既然有了vector为什么还需要array STL中既然有了vec…