【LeetCode 热题 100】二叉树 系列
📁 104. 二叉树的最大深度
深度就是树的高度,即只要左右子树其中有一个不为空,就继续往下递归,知道节点为空,向上返回。
int maxDepth(TreeNode* root) {if(root == nullptr)return 0;return max(maxDepth(root->left) , maxDepth(root->right)) + 1;}
📁 94. 二叉树的中序遍历
中序遍历就是先访问左子树,再访问根节点,最后访问右子树。
class Solution {
public:vector<int> ans;vector<int> inorderTraversal(TreeNode* root) {dfs(root); return ans;}void dfs(TreeNode* root){if(root == nullptr)return ;dfs(root->left);ans.push_back(root->val);dfs(root->right);}
};
📁 226. 翻转二叉树
对二叉树来一遍后序遍历,即先将左右子树翻转,保存反转后的左右子树的根节点,让root左右子树指针分别指向右子树,左子树。
TreeNode* invertTree(TreeNode* root) {if(root == nullptr)return root;TreeNode* left = invertTree(root->left);TreeNode* right = invertTree(root->right);root->right = left;root->left = right;return root;}
📁 101. 对称二叉树
求对称二叉树,我们只需要判断左右子树是否满足满足下面这些性质:1. 左右子树根节点相同;2. 左子树的右子树 = 右子树的的左子树;3. 左子树的左子树 = 右子树的右子树。
bool isSymmetric(TreeNode* root) {return isSameTree(root->left , root->right);}bool isSameTree(TreeNode* t1 , TreeNode* t2){if(t1 == nullptr && t2 == nullptr)return true;if(t1 == nullptr || t2 == nullptr)return false;if(t1->val != t2->val)return false;return isSameTree(t1->left , t2->right) && isSameTree(t1->right , t2->left);}
📁 543. 二叉树的直径
以某个节点为根节点,统计做左子树的最长路径,在统计右子树的最长路径,左右子树最长路径相加就是该二叉树的直径。
递归函数向上返回该二叉树的最长路径。
int ans = 0;int diameterOfBinaryTree(TreeNode* root) {depth(root);return ans;}int depth(TreeNode* root){if(root == nullptr)return 0;int left = depth(root->left);int right = depth(root->right);ans = max(ans , left + right);return max(left , right) + 1;}
📁 102. 二叉树的层序遍历
我们使用队列来完成二叉树的层序遍历,利用队列 [先入先出]的特性,将每一层的节点入队列,出队列按一层节点个数出队列。
如果出队列的每一个节点左右子树指针还有节点,在入队列,因为之前已经确定好了每一层节点个数,因此出队列时不回影响新入队列的节点。
vector<vector<int>> levelOrder(TreeNode* root) {if(root == nullptr)return vector<vector<int>>();vector<vector<int>> ret; queue<TreeNode*> q;q.push(root);while(!q.empty()){vector<int> tmp; //记录该层每一个节点的值int sz = q.size(); //记录该层的节点个数for(int i = 0 ; i < sz ; ++i){ TreeNode* node = q.front();q.pop();tmp.push_back(node->val);if(node->left)q.push(node->left);if(node->right)q.push(node->right);}ret.push_back(tmp);}return ret;}
📁 108. 将有序数组转换为二叉搜索树
二叉搜索树的特征就是,左子树所有节点的值都小于根节点的值,右子树所有节点的值都大于根节点的值;对二叉搜索树进行前序遍历得到的结果是一个有序数组。
对于本题,我们就可以采用二分+前序递归的方法,将中间值mid作为根节点,比mid小的放在左子树,比mid大的放在右子树。
TreeNode* dfs(vector<int>& nums , int left , int right){if(left > right)return nullptr;int mid = (left + right) >> 1;TreeNode* node = new TreeNode(nums[mid]);node->left = dfs(nums , left , mid - 1);node->right = dfs(nums , mid + 1 , right);return node;}TreeNode* sortedArrayToBST(vector<int>& nums) {return dfs(nums , 0 , nums.size() - 1);}
📁 98. 验证二叉搜索树
二叉搜索树的特征就是,左子树所有节点的值都小于根节点的值,右子树所有节点的值都大于根节点的值;对二叉搜索树进行前序遍历得到的结果是一个有序数组。
根绝二叉树性质我们可以知道,对二叉树进行前序遍历时,root节点的值一定大于上一个已经被遍历的节点值(左子树中最右节点)prev。
递归函数返回值为是否为二叉搜索树,先遍历左子树是否二叉搜索树,在判断根节点值是否大于prev,然后在判断右子树是否是二叉搜索树。
特殊情况:初始化prev值为最小值;如果是空间点nullptr,返回值为true。
long prev = LONG_MIN;bool dfs(TreeNode* root){if(root == nullptr)return true;bool left = dfs(root->left);if(!left)return false;if(root->val <= prev)return false;prev = root->val;bool right = dfs(root->right);return right;}bool isValidBST(TreeNode* root) {return dfs(root); }
📁 230. 二叉搜索树中第 K 小的元素
从左往右递归,即前序遍历,依次--k,知道找到k为0的节点,这就是第k小的元素节点。
class Solution {
public:int count = 1;int ret = 0;int kthSmallest(TreeNode* root, int k) {count = k;dfs(root);return ret; }void dfs(TreeNode* root){if(root == nullptr)return ;dfs(root->left);count--;if(count == 0){ret = root->val;return ;}dfs(root->right);}
};
📁 199. 二叉树的右视图
l利用BFS进行层序遍历,记录下来每一层的最后一个节点元素即可。
class Solution {
public:vector<int> ret;vector<int> rightSideView(TreeNode* root) {if(root == nullptr)return vector<int>();queue<TreeNode*> q;q.push(root);while(!q.empty()){int sz = q.size();for(int i = 0 ; i < sz; ++i){TreeNode* node = q.front(); q.pop();if(node->left)q.push(node->left);if(node->right)q.push(node->right);if(i == sz - 1)ret.push_back(node->val);}}return ret; }
};
📁 114. 二叉树展开为链表
判断左子树是否为空,如果为空,当前节点root不需要展开,已经展开为链表,处理当前节点的右子树。
如果不为空,需要找到左子树的最右节点作为右子树的根节点的前驱节点,当前节点root->left值为nullptr,右子树为左子树的根节点,处理完当前层后展开为链表,然后处理右子树。
class Solution {
public:void flatten(TreeNode* root) {TreeNode* cur = root;while(cur){if(cur->left){TreeNode* left = cur->left;TreeNode* prev = left;while(prev->right)prev = prev->right;prev->right = cur->right;cur->right = left;cur->left = nullptr;}cur = cur->right;}}
};
📁 105. 从前序与中序遍历序列构造二叉树
本题默认是所有值不重复
前序遍历的第一个节点一定是根节点,我们在中序遍历中查找根节点,即可找到左子树和右子树。
因此,递归遍历拿到prev中第一个节点一定是根节点,创建根节点,递归创建左子树根节点,在递归创建右子树根节点,直到数组中没有数据再能创建节点。
我们在中序遍历中找到根节点,就能知道左子树长度和右子树长度,我们采用空间换时间的方法,记录下来中序遍历中每个节点对应的下标。
class Solution {
public:unordered_map<int,int> index;TreeNode* myBuildTree(vector<int>& preorder, vector<int>& inorder , int prev_left , int prev_right,int in_left , int in_rihgt){if(prev_left > prev_right || in_left > in_rihgt)return nullptr;//记录前序遍历中root的下标 以及中序遍历中root的下标int in_root = index[preorder[prev_left]];//新建节点TreeNode* root = new TreeNode(preorder[prev_left]);//记录左子树的个数int sz = in_root - in_left;root->left = myBuildTree(preorder , inorder , prev_left + 1 , prev_left + sz, in_left , in_root - 1);root->right = myBuildTree(preorder , inorder , prev_left + 1 + sz , prev_right, in_root + 1 , in_rihgt);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int sz = preorder.size();for(int i = 0 ; i < sz ; ++i)index[inorder[i]] = i;return myBuildTree(preorder , inorder , 0 , sz - 1 , 0 , sz - 1);}
};
📁 437. 路径总和 III
我们采用前缀和的方法,从根节点开始,不断地往某一分支+root->val值为cur,如果满足公式:targetNum + ? = cur,如果 ? 存在,就表明上述公式成立,targetNum一定存在,ans += 齐前缀和为 ?的个数。
步骤:判断从当前节点往上是否满足公式,如果满足,ans += 前缀和为 ?的个数;在判断左右子树,即ans += 左右子树中满足公式的前缀和的个数。
class Solution {
public:unordered_map<long long , long long> hash;int pathSum(TreeNode* root, int targetSum) {hash[0] = 1;return dfs(root , 0 , targetSum);}int dfs(TreeNode* root , long long cur ,long long targetSum){if(root == nullptr)return 0;int ans = 0;cur += root->val;if(hash.find(cur - targetSum) != hash.end())ans += hash[cur - targetSum];hash[cur]++;ans += dfs(root->left , cur , targetSum);ans += dfs(root->right , cur , targetSum);hash[cur]--;return ans; }
};
📁 236. 二叉树的最近公共祖先
分为以下三种情况,递归查找p节点和q节点,如果找到向上返回,如果没有返回nullptr,分别查找左右子树。
1. 如果左右子树递归结果为空,说明没有找到p,q节点,返回nullptr。
2. 如果左子树为空,说明p和q节点在右子树中,p或q节点为另一个节点的最近公共祖先。
3. 右子树为空,同理可得。
4. 如果左右子树都不为空,说明此时,root为p和q的最近公共祖先。
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root == nullptr || root == p || root == q)return root;TreeNode* left = lowestCommonAncestor(root->left , p , q);TreeNode* right = lowestCommonAncestor(root->right , p , q);if(!left)return right;if(!right)return left;return root;}
};
📁 124. 二叉树中的最大路径和
本题,我们采用后序遍历的思路,先查找左子树中最大值的路径,最查找右子树中最大值的路径,然后+上根节点的值,记录下来最大值即可。
返回值为,从根节点开始,到左右子树中找到一条值最大的路径,向上返回该路径的值+根节点的值。
递归结束条件就是找到叶子节点,向上返回。
class Solution {
public:int ret = INT_MIN;int maxPathSum(TreeNode* root) {dfs(root);return ret; }int dfs(TreeNode* root){if(root == nullptr)return 0;int left = max(0 , dfs(root->left));int right = max(0 , dfs(root->right));ret = max(ret , root->val + left + right);return root->val + max(left , right);}
};
相关文章:

【LeetCode 热题 100】二叉树 系列
📁 104. 二叉树的最大深度 深度就是树的高度,即只要左右子树其中有一个不为空,就继续往下递归,知道节点为空,向上返回。 int maxDepth(TreeNode* root) {if(root nullptr)return 0;return max(maxDepth(root->lef…...

用drawdb.app可视化创建mysql关系表
平时自己建表,没有可视化图形参考 为了便于理解,用drwadb画mysql关系表 drawDB | Online database diagram editor and SQL generator...

火绒互联网安全软件:自主引擎,精准防御
在数字时代,网络安全是每一个用户都必须重视的问题。无论是个人用户还是企业用户,都需要一款高效、可靠的反病毒软件来保护设备免受恶意软件的侵害。今天,我们要介绍的 火绒互联网安全软件,就是这样一款由资深工程师主导研发并拥有…...
Golang 应用的 CI/CD 与 K8S 自动化部署全流程指南
一、CI/CD 流程设计与工具选择 1. 技术栈选择 版本控制:Git(推荐 GitHub/GitLab)CI 工具:Jenkins/GitLab CI/GitHub Actions(本文以 GitHub Actions 为例)容器化:Docker Docker Compose制品库…...

【前端基础】8、CSS的选择器
一、什么是选择器? 根据一定的规则选出符合条件的HTML元素,从而为他们添加各种特定的样式。 二、选择器分类 通用选择器元素选择器类选择器id选择器属性选择器后代选择器兄弟选择器选择器组伪类 三、通用选择器(*) 作用&…...

Gitee Team:关键领域行业DevSecOps落地的项目管理引擎
在全球数字化转型浪潮下,关键领域行业的软件研发正面临前所未有的挑战与机遇。国产化进程的加速推进与国防装备的智能化转型,对软件研发效能和质量提出了更高要求。在这样的背景下,Gitee Team作为国内领先的研发协作平台,正在为关…...
【Redis】键值对数据库实现
目录 1、背景2、五种基本数据类型对应底层实现3、redis数据结构 1、背景 redis是一个(key-value)键值对数据库,其中value可以是五大基本数据类型:string、list、hash、set、zset,这五大基本数据类型对应着不同的底层结…...
什么是 NoSQL 数据库?它与关系型数据库 (RDBMS) 的主要区别是什么?
我们来详细分析一下 NoSQL 数据库与关系型数据库 (RDBMS) 的主要区别。 什么是 NoSQL 数据库? NoSQL (通常指 “Not Only SQL” 而不仅仅是 “No SQL”) 是一类数据库管理系统的总称。它们的设计目标是解决传统关系型数据库 (RDBMS) 在某些场景下的局限性…...

网址为 http://xxx:xxxx/的网页可能暂时无法连接,或者它已永久性地移动到了新网址
这是由于浏览器默认的非安全端口所导致的,所谓非安全端口,就是浏览器出于安全问题,会禁止一些网络浏览向外的端口。 避免使用6000,6666这样的端口 6000-7000有很多都不行,所以尽量避免使用这个区间 还有在云服务器中,…...
《智能网联汽车 自动驾驶功能场地试验方法及要求》 GB/T 41798-2022——解读
目录 1. 适用范围与核心目标 2. 试验核心要求 2.1 试验场地与环境 2.2 试验设备与数据采集 2.3 试验车辆要求 3. 试验过程与通过条件 4. 关键试验场景与方法 4.1 交通信号识别及响应 4.2 基础设施与障碍物识别 4.3 行人及非机动车场景 4.4 紧急避险与风险策略 5. 特…...

鸿蒙跨平台开发教程之Uniapp布局基础
前两天的文章内容对uniapp开发鸿蒙应用做了一些详细的介绍,包括配置开发环境和项目结构目录解读,今天我们正式开始写代码。 入门新的开发语言往往从Hello World开始,Uniapp的初始化项目中已经写好了一个简单的demo,这里就不再赘述…...

uniapp使用npm下载
uniapp的项目在使用HBuilder X创建时是不会有node_modules文件夹的,如下图所示: 但是uni-app不管基于哪个框架,它内部一定是有node.js的,否则没有办法去实现框架层面的一些东西,只是说它略微有点差异。具体差异表现在…...
uni-app微信小程序登录流程详解
文章目录 uni-app微信小程序登录流程实战详解微信小程序登录流程概述1. 获取登录凭证(code)2. 发送登录请求3. 保存登录态4. 登录状态管理5. 应用登录状态请求拦截器中添加 token自动登录页面路由守卫 使用 Vuex 集中管理登录状态登录组件示例登录流程最…...
【C++游戏引擎开发】第34篇:C++实现反射
一、反射系统概述 1.1 反射的核心概念 1.1.1 运行时自省能力 反射允许程序在运行时动态获取和操作自身的类型信息。这种能力突破了静态类型语言的限制,使得开发者可以: 检查对象类型及其成员结构动态创建未在编译期确定的类型实例实现类型无关的通用操作接口1.1.2 元数据驱…...

C# 的异步任务中, 如何暂停, 继续,停止任务
namespace taskTest {using System;using System.Threading;using System.Threading.Tasks;public class MyService{private Task? workTask;private readonly SemaphoreSlim semaphore new SemaphoreSlim(0, 1); // 初始为 0,Start() 启动时手动放行private read…...
langchain4j中使用milvus向量数据库做RAG增加索引
安装milvus向量数据库 官方网址 https://milvus.io/zh 使用docker安装milvus mkdir -p /data/docker/milvus cd /data/docker/milvus wget https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh#在docker中启动milvus sh standalone_emb…...
MySQL SQL Mode及其说明
以下是MySQL中所有支持的SQL Mode及其说明,综合了多个来源的信息并进行了分类整理: 一、严格模式相关 STRICT_TRANS_TABLES 对事务型存储引擎(如InnoDB)启用严格数据校验。若插入非法值(如类型不符、超出范围等&#…...
Web前端最新导航
前言 本文列出了很多与前端有关的常见网站、博客、工具等,整体来看比较权威。有些东西已经过时了,我就不列出来了。学是一方面,也是最主要的方面;但还有一个作用,比如,“这个前端框架你都不知道啊”、“这个…...

2025年AI工程师认证深度解析:AAIA认证体系全景指南与实战策略
一、IAAAI认证体系演进与价值定位 1.1 国际人工智能认证发展现状 全球人工智能认证市场呈现显著分化态势。据Gartner 2025Q1报告显示,北美市场以IEEE/ACM双认证体系为主导(市占率38%),欧盟区推行AI Act合规认证(强制…...
CentOS 和 RHEL
CentOS 和 RHEL(Red Hat Enterprise Linux)关系非常紧密,简而言之: CentOS 最初是 RHEL 的免费、开源克隆版,几乎与 RHEL 二进制兼容。 CentOS 原是 RHEL 的“免费双胞胎”,但已被放弃,现在推荐…...
flask开启https服务支持
目录 一、背景 二、开启https支持 三、自签名 1、安装openssl 2、验证安装 3、自签名 四、编写代码 五、访问https接口 一、背景 最近在做自动化业务,需要兼容现在主流的框架开发的前端页面,于是到github找到了几个项目,clone下来项目并…...

统计服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
文章目录 一、背景二、说明三、页面四、代码 前端 MonitorServiceProcessPage.vueMonitorServiceProcessTable.vueMonitorServiceProcessTableButton.vueaddMonitorTask.vueproductOperation.vueshowMonitorTask.vueMonitorSystemLog.vueMonitorTask.vueMonitorTaskLog.vueReal…...
【SGL】Scatter-Gather List内存传输技术
文章目录 1. What is SGL?2. sgl内存传输的原理2.1 核心思想2.2 sgl数据结构2.3 摘链和挂链 3. 零拷贝技术3.1 问题背景3.2 零拷贝的核心思想及实现方式 4. sgl在存储行业的应用 1. What is SGL? sgl(Scatter-Gather List)内存传…...

-MAC桢-
MAC桢和IP的关系: 主机A想跨网络和B通信需要IP地址进行路由选择,但一个局域网,比如路由器进行路由选择之前,首先要将数据包发送给路由器B,也就是局域网通信也就是同一个网段的主机进行通信,所以必须通过mac…...

安装:Kali2025+Docker
安装:Kali2025Docker Kali2025安装 直接官网下载WMware版本 https://www.kali.org/get-kali/#kali-virtual-machines 直接打开运行 初始用户密码 kali/kali sudo -i 命令切换到root 更换镜像 切换到其他可用的 Kali Linux 镜像源可能会解决问题,可以使用国内的镜像源&…...

Linux云计算训练营笔记day04[Rocky Linux中的命令:mv、cp、grep(^$)、tar、重定向>和>>]
mv 移动(剪切) 源数据会消失 格式: mv 源文件 目标路径 touch /opt/a.txt 创建文件 mv /opt/a.txt /root 移动文件,没有改名 mkdir gongli 创建目录 mv gongli /opt/ 移动目录,没有改名 mv /opt/gongli tedu 移动目录,改名了 …...

AbMole Olaparib:打破常规,用PARP抑制重塑肿瘤研究
在当今的生物医学研究领域,Olaparib(AZD2281,AbMole,M1664)作为一种重要的PARP(聚腺苷二磷酸核糖聚合酶)抑制剂,受到了广泛关注。Olaparib可干扰 DNA 单链断裂的修复,从而…...
RPC、gRPC和HTTP的区别
RPC 只是一种屏蔽远程过程调用的设计,它与HTTP不是对立的,两者不是一个层面的概念。 RPC底层通信可以使用TCP实现(如Thrift),也可以使用HTTP实现(如gRPC),其本身并无限制。 1. 概念…...

Windows重置网络,刷新缓存
同时按键盘上的【Windows】键和【S】键,弹出搜索框,输入 命令提示符 在“最佳匹配”下的【命令提示符】上右键,点击【以管理员身份运行】 1弹出一个窗口,在光标闪烁的位置,直接输入【netsh winsock reset】࿰…...
Ref是什么
在 React 中,ref 是一种用于访问 DOM 元素或组件实例的机制。它允许你在组件中直接操作 DOM 元素,或者访问子组件的实例。ref 的使用场景非常广泛,包括表单操作、焦点控制、动画等。以下是关于 ref 的详细讲解以及在项目中的常见使用场景。 …...