leetcode hot100 二叉树(二)

article/2025/7/2 14:55:20

书接上回:https://blog.csdn.net/weixin_74129837/article/details/148367615?spm=1001.2014.3001.5501

8.验证二叉搜索树

维护一个min_val和max_val,限制当前结点的合法值范围。min_val和max_val动态变化。

class Solution {
public:bool check(TreeNode* node,long min_val,long max_val){if(!node) return true;if(node->val<=min_val||node->val>=max_val) return false;  //注意定义,等于也不行return check(node->left,min_val,node->val)&&check(node->right,node->val,max_val);}bool isValidBST(TreeNode* root) {return check(root,LONG_MIN,LONG_MAX);}
};

9.二叉搜索树中第k小的元素

在BST中,中序遍历(左-根-右)会按升序访问所有节点

因此,第k个被访问的节点就是第k小的元素。

代码本质上是迭代实现的中序遍历,并通过提前终止(剪枝)来优化。

算法流程:向左深入->回溯到父结点->转向右子树。

class Solution {
public:int kthSmallest(TreeNode* root, int k) {stack<TreeNode*> stk;while(root||stk.size()){while(root){stk.push(root);  root=root->left;} root=stk.top();  //取出最后遍历到的父结点(相当于回溯)stk.pop();if(--k==0) return root->val;root=root->right;}return root->val;}
};

10.二叉树的右视图

dfs遍历,且优先遍历右子树。

如果层数==res大小,说明当前层还未加入结点,即本次递归到的结点是当前层右数第一个结点。

class Solution {
public:void dfs(TreeNode* root,vector<int>& res,int u){if(!root) return ;//在搜索过程中总是先访问右子树//对于每一层来说,这层见到的第一个结点一定是最右边的结点//u==res.size()时,当前层级u还没有被记录到res中(res 的索引是0到u-1,共u层)if(u==res.size()) res.push_back(root->val);dfs(root->right,res,u+1);dfs(root->left,res,u+1); }vector<int> rightSideView(TreeNode* root) {vector<int> res;if(!root) return res;dfs(root,res,0);return res;}
};

 11.二叉树展开为链表

核心:展开的单链表与二叉树先序遍历的顺序相同。

class Solution {
public:void flatten(TreeNode* root) {vector<TreeNode*> nodes; // 用于存储先序遍历的结果preorderTraversal(root,nodes); // 获取先序遍历结果int n=nodes.size();for (int i=1;i<n;i++){TreeNode* prev=nodes[i-1];TreeNode* curr=nodes[i];prev->left=nullptr; // 左子指针置空prev->right=curr;   // 右子指针指向下个节点}}//先序遍历:根->左->右void preorderTraversal(TreeNode* root,vector<TreeNode*> &l){if(root){l.push_back(root);preorderTraversal(root->left,l);preorderTraversal(root->right,l);}}
};

12.从前序与中序遍历序列构造二叉树

class Solution {
private:unordered_map<int,int> index;
public:TreeNode* build(vector<int>& pre,vector<int>& in,int pre_left,int pre_right,int in_left,int in_right){if(pre_left>pre_right) return nullptr;int pre_root=pre_left;  //pre_root是索引int in_root=index[pre[pre_root]];int left_size=in_root-in_left;TreeNode* root=new TreeNode(pre[pre_root]);root->left=build(pre,in,pre_left+1,pre_left+left_size,in_left,in_root-1);root->right=build(pre,in,pre_left+left_size+1,pre_right,in_root+1,in_right);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int n=preorder.size();for(int i=0;i<n;i++) index[inorder[i]]=i;return build(preorder,inorder,0,n-1,0,n-1);}
};

13.路径总和

        如图,先利用先序遍历序列确定根节点,再利用中序遍历序列递归子树,关键是递归边界的确定。

class Solution {
public:int dfs(TreeNode* node,long sum,int target){if(!node) return 0;int cnt=0;if(sum+node->val==target) cnt++;cnt+=dfs(node->left,sum+node->val,target);cnt+=dfs(node->right,sum+node->val,target);return cnt;} int pathSum(TreeNode* root, int targetSum) {if(!root) return 0;int cnt=dfs(root,0,targetSum);cnt+=pathSum(root->left,targetSum);cnt+=pathSum(root->right,targetSum);return cnt;}
};

14.二叉树的最近公共祖先

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(!root) return nullptr;if(p==root||q==root) return root;TreeNode* left=lowestCommonAncestor(root->left,p,q);TreeNode* right=lowestCommonAncestor(root->right,p,q);if(right&&left) return root;  //左右节点都有,最近公共祖先是根结点if(left) return left;  //只有左结点if(right) return right;  //只有右结点return nullptr;}
};

15.二叉树的最大路径和

  • 后序遍历:采用DFS的后序遍历方式(左右根)来遍历整棵树。
  • 计算单边最大增益:对于每个节点,计算其左子树和右子树能提供的最大增益(如果增益为负则取0,表示不选择该子树)。
  • 更新全局最大值:对于当前节点,计算包含该节点及其左右子树的最大路径和(即node->val + left_gain + right_gain),并更新全局最大值max_sum
  • 返回单边最大路径:向上返回时只能选择左或右子树中增益较大的一边加上当前节点的值。
class Solution {
public:int dfs(TreeNode* node,int& max_sum){if(!node) return 0;int left_gain=max(dfs(node->left,max_sum),0);int right_gain=max(dfs(node->right,max_sum),0);int curr_sum=node->val+left_gain+right_gain;max_sum=max(max_sum,curr_sum);return node->val+max(left_gain,right_gain);}int maxPathSum(TreeNode* root) {int max_sum=INT_MIN;dfs(root,max_sum);return max_sum;}
};


http://www.hkcw.cn/article/VCBQnMwhaM.shtml

相关文章

【Linux】基础文件IO

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 前言 无论是日常使用还是系统管理&#xff0c;文件是Linux系统中最核心的概念之一。对于初学者来说&#xff0c;理解文件是如何被创建、读取、写入以及存储…

MYSQL MGR高可用

1&#xff0c;MYSQL MGR高可用是什么 简单来说&#xff0c;MySQL MGR 的核心目标就是&#xff1a;确保数据库服务在部分节点&#xff08;服务器&#xff09;发生故障时&#xff0c;整个数据库集群依然能够继续提供读写服务&#xff0c;最大限度地减少停机时间。 2. 核心优势 v…

【java面试】MySQL篇

MySQL篇 一、总体结构二、优化&#xff08;一&#xff09;定位慢查询1.1 开源工具1.2Mysql自带的慢日志查询1.3 总结 &#xff08;二&#xff09;定位后优化2.1 优化2.2 总结 &#xff08;三&#xff09;索引3.1 索引3.2 索引底层数据结构——B树3.3 总结 &#xff08;四&#…

头像预览和上传

在写一个项目的时候&#xff0c;遇到了头像修改这个功能的需求&#xff0c;在最开始的学习中发现可以通过type为file的input文件读取图片&#xff0c;然后将其转换为DataUrl格式&#xff0c;最终作为Ima元素的src即可在页面上展示图片。但到后面开始写交互的时候发现DataUrl格式…

解锁效率新高度:Agent Zero智能助手框架

探索Agent Zero AI框架&#xff1a;您的个性化智能助手 在迅速发展的科技世界&#xff0c;Agent Zero AI框架为我们揭开了一个全新的大门。被设计成能够与用户同步成长与学习的智能助手&#xff0c;Agent Zero展现了它作为个性化使用工具的非凡潜力。在本篇文章中&#xff0c;…

第43节:Vision Transformer (ViT)视觉领域的革命性架构

1. ViT的诞生背景与核心思想 Vision Transformer (ViT) 是2020年由Google Research团队提出的一种革命性计算机视觉架构,它将自然语言处理(NLP)领域中大获成功的Transformer模型引入到计算机视觉任务中。这一创新彻底改变了传统卷积神经网络(CNN)在视觉任务中的主导地位,为图…

leetcode0513. 找树左下角的值-meidum

1 题目&#xff1a;找树左下角的值 官方标定难度&#xff1a;中 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 示例 2: 输入: [1,2,3,4,null,5,6,null,null,7]…

从webshell管理工具(蚁剑 冰蝎 哥斯拉 菜刀 哥斯拉等)程控制主机后,再将这个控制能力上线到MSF 为什么要这么做了?一篇文章告诉你

目录 一、为什么Webshell管理工具需要上线到Metasploit&#xff1f; 什么情况下需要上线到Metasploit&#xff1f; 二、常见Webshell管理工具及上线Metasploit的步骤 1. 蚁剑&#xff08;AntSword&#xff09;上线到Metasploit 上线步骤&#xff1a; 实际案例&#xff1a…

【Ragflow】24.Ragflow-plus开发日志:增加分词逻辑,修复关键词检索失效问题

概述 在RagflowPlus v0.3.0 版本推出之后&#xff0c;反馈比较多的问题是&#xff1a;检索时&#xff0c;召回块显著变少了。 如上图所示&#xff0c;进行检索测试时&#xff0c;关键词相似度得分为0&#xff0c;导致混合相似度(加权相加得到)也被大幅拉低&#xff0c;低于设定…

YOLOv5 :训练自己的数据集

- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/rnFa-IeY93EpjVu0yzzjkw) 中的学习记录博客** - **&#x1f356; 原作者&#xff1a;[K同学啊](https://mtyjkh.blog.csdn.net/)** 我们接着上一篇文章配置完YOLOv5需要的环境后&#…

【Unity】云渲染

1 前言 最近在搞Unity云渲染的东西&#xff0c;所以研究了下官方提供的云渲染方案Unity Renderstreaming。注&#xff1a;本文使用的Unity渲染管线是URP。 2 文档 本文也只是介绍基本的使用方法&#xff0c;更详细内容参阅官方文档。官方文档&#xff1a;Unity Renderstreamin…

每日一道面试题---ArrayList的自动扩容机制(口述版本)

首先&#xff0c;ArrayList是基于动态数组实现的&#xff0c;它的容量是可以动态增长的&#xff0c;ArrayList的默认容量是10&#xff0c;当我们向ArrayList中插入一个数据时&#xff0c;第一步&#xff0c;会先进行一个条件的校验操作&#xff0c;先去判断ArrayList是不是一个…

分布式锁优化:使用Lua脚本保证释放锁的原子性问题

分布式锁优化&#xff08;二&#xff09;&#xff1a;使用Lua脚本保证释放锁的原子性问题 &#x1f4bb;黑马视频链接&#xff1a;Lua脚本解决多条命令原子性问题 在上一章节视频实现了一个可用的Redis分布式锁&#xff0c;采用SET NX EX命令实现互斥和过期自动释放机制&…

B1、进度汇报(— 25/05/31)

本文档汇总了各成员在 2025 年 5 月 11 日 ~ 5 月 31 日完成的工作。我们遇到了进度问题&#xff08;收工后需反思&#xff09;&#xff1a; 本学期第十四周&#xff08;05/19 ~ 05/25&#xff09;有相当多课程需要提交实验结果或上台展示。本学期第十六周&#xff08;06/02 ~…

BUUCTF[极客大挑战 2019]Havefun 1题解

BUUCTF[极客大挑战 2019]Havefun 1题解 题目分析解题理解代码逻辑&#xff1a;构造Payload&#xff1a; 总结 题目分析 生成靶机&#xff0c;进入网址&#xff1a; 首页几乎没有任何信息&#xff0c;公式化F12打开源码&#xff0c;发现一段被注释的源码&#xff1a; 下面我们…

常见算法题目5 -常见的排序算法

常见算法题目5 -常见的排序算法 本文介绍常见的排序算法的思路及代码实现(都是按照从小到大排列)&#xff0c;包括冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。 1.冒泡排序 思路&#xff1a;重复遍历数组&#xff0c;依次比较相邻元素&#xff0c;若顺序错误…

3.需求分析与测试用例设计方法

设计方法 测试点 定义: 测试时需要考虑的可测试方面&#xff0c;不同公司可能称为"检查点"或其它名称特点: 是需求分析的最后一个环节&#xff0c;用于解决"测哪里"和"怎么测"的问题举例说明: 如同打架时的各种招数&#xff0c;如直接约架、设…

【PCB设计】STM32开发板——电源设计

电源稳压器&#xff08;Power Regulator&#xff09;是一种在电源电压或者负载电流发生变化的时候&#xff0c;依然能够提供稳定输出电压的元件。 一、关于LDO电路 1.引入 小灯泡实验 2.LDO原理 3.LDO芯片结构框图 PNP型三极管&#xff0c;Ube上升&#xff0c;截至&#xff…

BUUCTF[HCTF 2018]WarmUp 1题解

BUUCTF[HCTF 2018]WarmUp 1题解 分析解题过程代码审计主体函数CHECK函数&#xff1a; 构造payload 总结 分析 启动靶机&#xff0c;进入网址&#xff0c;是一张滑稽的表情包&#xff1a; 程序化F12查看源码&#xff1a; 发现注释内容&#xff0c;访问 url:/source.php得到…

如何使用DAXStudio将PowerBI与Excel连接

如何使用DAXStudio将PowerBI与Excel连接 之前分享过一篇自动化文章&#xff1a;PowerBI链接EXCEL实现自动化报表&#xff0c;使用一个EXCEL宏工作薄将PowerBI与EXCEL连接起来&#xff0c;今天分享另一个方法&#xff1a;使用DAX Studio将PowerBI与EXCEL连接。 下面是使用DAX S…