【三十二】【算法分析与设计】深搜(2),98。 验证二叉搜索树,不同方式定义递归函数,230。 二叉搜索树中第 K 小的元素,257。 二叉树的所有路径

98. 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左

  • 子树

  • 只包含 小于 当前节点的数。

  • 节点的右子树只包含 大于 当前节点的数。

  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:root = [2,1,3] 输出:true

示例 2:

输入:root = [5,1,4,null,null,3,6] 输出:false 解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 10(4)]

  • -2(31) <= Node.val <= 2(31)1

两个递归

定义 isValidBSTHelper 递归函数,判断 root 树是否是二叉搜索树。

维护递归定义内部逻辑,左子树是二叉搜索树,右子树也是二叉搜索树,同时自身也是二叉搜索树,此时 return true

判断左右子树是不是二叉搜索树,交给递归函数即可,我们只需要判断自身是否为二叉搜索树。

如果左子树的所有值都小于 root->val,右子树的所有值都大于 root->val,此时自身也是二叉搜索树。

递归出口,root==nullptr,return true

定义递归函数 dfs,判断 root 树是否在范围(minVal,maxVal)之中。

维护递归定义内部逻辑,root->val 在范围内,左子树和右子树也在范围内。

递归的出口,如果 root==nullptr,return true

 
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {
public:bool isValidBST(TreeNode* root) { return isValidBSTHelper(root); }private:bool isValidBSTHelper(TreeNode* node) {if (node == nullptr)return true;return isValidBSTHelper(node->left) && isValidBSTHelper(node->right) &&dfs(node->left, LONG_MIN, node->val) &&dfs(node->right, node->val, LONG_MAX);}bool dfs(TreeNode* root, long minVal, long maxVal) {if (root == nullptr)return true;if (root->val <= minVal || root->val >= maxVal)return false;return dfs(root->left, minVal, maxVal) &&dfs(root->right, minVal, maxVal);}
};

节点正确存在

另一种递归思维,定义递归函数 isValidBSTHelper 判断 node 这棵树的全部节点是否正确存在。

root 是否是二叉搜索树,取决于 root 这棵树的的所有节点是否正确存在。

维护递归的内部逻辑,node 这棵树全部节点是否正确存在,如果左子树全部节点正确存在,右子树全部节点正确存在,node 根节点也正确存在,那么就算全部正确存在。

node 根节点是否正确存在,取决于他的父亲结点,父亲节点会给予一个范围,如果在父亲结点的左子树,那么 node->val 必须小于父亲结点的 val,如果在父亲结点的右子树,那么 node->val 必须大于父亲结点的 val

递归的出口,如果 node==nullptr,return true

 
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {
public:bool isValidBST(TreeNode* root) {return isValidBSTHelper(root, LONG_MIN, LONG_MAX);}private:bool isValidBSTHelper(TreeNode* node, long minVal, long maxVal) {if (node == nullptr)return true;if (node->val <= minVal || node->val >= maxVal)return false;return isValidBSTHelper(node->left, minVal, node->val) &&isValidBSTHelper(node->right, node->val, maxVal);}
};

中序遍历有序

利用二叉搜索树的性质判断。二叉搜索树中序遍历的结果是有序序列。

root 是否是二叉搜索树,取决于 root 这棵树的中序遍历序列是否有序。

定义递归函数 isValidBST 判断 root 树中序遍历序列是否是有序序列。

定义 prev 表示前驱节点的值。

维护定义的内部逻辑,判断左子树中序遍历序列是否是有序序列,判断 root 根节点的值是否大于前驱节点的值。然后再判断右子树中序遍历序列是否是有序序列。

递归出口,如果 root==nullptr,return true

剪枝操作,如果左子树中序遍历序列不是有序,说明 root 这棵树中序不是有序,直接返回 false

如果 root 根节点的值小于等于前驱节点,说明 root 这棵树中序不是有序,直接返回 false

如果右子树中序遍历序列不是有序,说明 root 这棵树中序不是有序,直接返回 false

 
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {long prev = LONG_MIN;public:bool isValidBST(TreeNode* root) {if (root == nullptr)return true;bool leftbool = isValidBST(root->left);if (leftbool == false)return false;bool cur = false;if (root->val > prev)cur = true;if (cur == false)return false;prev = root->val;bool rightbool = isValidBST(root->right);if (rightbool == false)return false;return true;}
};

230. 二叉搜索树中第 K 小的元素

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

示例 1:

输入:root = [3,1,4,null,2], k = 1 输出:1

示例 2:

输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3

提示:

  • 树中的节点数为 n

  • 1 <= k <= n <= 10(4)

  • 0 <= Node.val <= 10(4)

进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

二叉搜索树的性质,中序遍历序列是有序的。

定义递归函数 dfs,先遍历左子树,再遍历自己,再遍历右子树。

定义全局变量 count retcount 记录还剩需要遍历节点数量,ret 记录最终答案。

 
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {
public:int count;int ret;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;dfs(root->right);return;}
};

257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [1,2,3,null,5] 输出:["1->2->5","1->3"]

示例 2:

输入:root = [1] 输出:["1"]

提示:

  • 树中节点的数目在范围 [1, 100]

  • -100 <= Node.val <= 100

定义递归函数 dfs,将 root 这棵树的所有路径填充到 ret 中。

定义 path 存储当前节点到一开始的 root 根节点的路径。

维护递归函数的内部逻辑,首先维护 path 变量,使 path 变量存储当前节点到一开始的 root 根节点的路径。

然后再判断此时是否是叶子节点,如果会死叶子节点说明 path 是其中一个有效的路径,填充到 ret 中。

如果不是叶子节点,path 路径后面添加->

然后将左子树路径填充到 ret 中,右子树路径填充到 ret 中。

递归出口,如果 root==0,return,此时不需要任何操作。

 
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {
public:vector<string> ret;vector<string> binaryTreePaths(TreeNode* root) {// 定义dfs找到所有路径,填充到ret中// 定义path 存储当前状态路径string path;dfs(root, path);return ret;}void dfs(TreeNode* root, string path) {if (root == nullptr)return;path += to_string(root->val);if (root->left == nullptr && root->right == nullptr)ret.push_back(path);path += "->";if (root->left)dfs(root->left, path);if (root->right)dfs(root->right, path);}
};

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

小程序 两页面间数据传递

页面1 页面2 实现效果&#xff1a;点击页面1 可以直接跳进页面2 实现过程&#xff1a; xhtml <view class"rank" wx:for"{{rankList}}" data-ids"{{item.id}}" data-names"{{item.name}}" data-description"{{item.descri…

C++ 11 初始化对象

1 概述 在C11中&#xff0c;可以使用多种方式来初始化对象。以下是一些常见的初始化方法&#xff1a; 2 列表初始化&#xff08;Uniform Initialization&#xff09; int a{10}; // 列表初始化一个整数 int b {10}; // 同样的&#xff0c;这也是列表初始化std::string str{…

行测——言语分析

行测——言语分析 1. 全文概括题1.1 做题思路1.2 例子1.2.1 概括内容1.2.2 标题类 2.中心理解题2.1 做题思路2.2 例子2.2.1 关键词清晰2.2.2 关键词不清晰 3. 逻辑顺序题3.1 做题思路3.2 例子3.2.1 划线部分填什么句子3.2.2 句子排序3.2.3 下一段讲什么3.2.4 细节分析题 4. 逻辑…

【C/C++】BST树的后序遍历

题目描述&#xff1a; 给定一个整数数组&#xff0c;判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true&#xff0c;否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树&#xff1a; 5 / \ 2 6 / \ 1 3 示例…

IPKISS ------ 导入 Lumerical S-matrix 仿真结果

IPKISS ------ 导入 Lumerical S-matrix 仿真结果 引言引言 这里给大家介绍一下如何使用 IPKISS 导入 Lumerical 中器件 S Matrix 的仿真结果。 import ipkiss3.all as i3 import matplotlib.pyplot as plt import numpy as nps_matrix = i3.device_sim.satrix1swep.from_tou…

[ RV1108_LINUX] 关于如何调整cpu中vdd_core的电压

问题描述 通过rv1108.dtsi调整其中dvfs节点下pd_core和pd_ddr对应频率的电压。发现修改后电压并没有改变&#xff0c;一直为11.25v。尝试了将pd_core下的operating-points中的1008000 1150000修改为1008000 1200000&#xff0c;也无作用。将operating-points中频率是留一个&am…

49. QT中的HTTP通信与JSON数据格式解析

1. 说明 最近参考B站以为博主的视频视频链接学习了一些在QT当中利用HTTP访问网页数据的相关知识,在此记录一下。在访问网页的时候主要用到的接口类包括:QNetworkAccessManager、QNetworkReply、QNetworkRequest,因为大部分网页数据都是以 JSON 格式保存的,所以在获取到网页…

Spring Boot Actuator

概述 Spring Boot Actuator是Spring Boot的一个功能模块&#xff0c;用于提供生产环境中常见的监控和管理功能。它提供了各种端点&#xff08;endpoints&#xff09;&#xff0c;可以用于监视应用程序的运行状况、收集应用程序的指标数据以及与应用程序进行交互。 以下是Spri…

Oracle基础-PL/SQL编程 备份

1、PL/SQL简介 PL/SQL块结构 约定&#xff1a;为了方便&#xff0c;本文后面把PL/SQL简称PL。 PL程序都是以块&#xff08;BLOCK&#xff09;为基本单位&#xff0c;整个PL块分三部分&#xff1a;声明部分&#xff08;使用DECLARE开头&#xff09;、执行部分(以BEGIN开头)和异…

数字人视频合成平台推荐

数字人讲解视频和全景作品的结合是一种全新的数字交互方式&#xff0c;可为用户提供更加直观和具有沉浸感的内容展示和交互体验&#xff0c;从而适用于诸如旅游、展览、博物馆、教育培训、泛房地产、以及娱乐和文化等应用场景。 当前数字人合成视频技术已经发展至日益成熟的阶…

Redission--分布式锁

Redission的锁的好处 Redission分布式锁的底层是setnx和lua脚本(保证原子性) 1.是可重入锁。 2.Redisson 锁支持自动续期功能&#xff0c;这可以帮助我们合理控制分布式锁的有效时长&#xff0c;当业务逻辑执行时间超出了锁的过期时间&#xff0c;锁会自动续期&#xff0c;避免…

学术论文写作

学术论文写作 摘自复旦张军平老师的书籍&#xff1a;高质量读研&#xff1a;教你如何写论文、做科研 标题 标题&#xff1a;1.明确研究内容&#xff1b;2.吸引眼球 摘要 字数&#xff1a;期刊&#xff08;300字左右&#xff09;、会议&#xff08;150字左右&#xff09;、毕…

python之while循环

while 循环是一种前测试循环结构&#xff0c;意味着在每次循环开始时先检查条件是否为真&#xff0c;如果为真&#xff0c;则执行循环体中的代码&#xff0c;然后再次检查条件。只有当条件为假时&#xff0c;循环才会终止。 通过结合实际问题和 while 循环&#xff0c;我们可以…

SSL通配符证书怎么选?看这里

通配符证书&#xff0c;作为一种特殊的数字证书类型&#xff0c;以其独特的优势在网络安全领域扮演着重要角色。相较于传统的单一域名证书&#xff0c;通配符证书能够为同一主域名下的所有子域名提供安全保护&#xff0c;显著提升管理效率&#xff0c;简化证书部署流程&#xf…

LandCover数据介绍与下载

一、LC介绍 土地覆盖&#xff08;Land Cover&#xff0c;LC&#xff09;是自然营造物和人工建筑物所覆盖的地表诸多要素的综合体。土地覆盖指地表所属的植被覆盖物(森林、草原、耕作植被等)或非植被覆盖物(冰雪、建筑物等)的具体类型&#xff0c;侧重描述地球表面的自然属性&a…

02 - 全加器和加法器

---- 整理自B站UP主 踌躇月光 的视频 1. 全加器 用门电路实现两个二进制数相加并求出和的组合线路&#xff0c;称为一位全加器。一位全加器可以处理低位进位&#xff0c;并输出本位加法进位。全加器比半加器多了一位进位。 1.1 实验 1&#xff1a;通过两个半加器设计全加器 1.…

IDEA无法连接虚拟机中的Redis的解决方案,无法连接Jedis,无法ping通虚拟机的解决方案

首先&#xff0c;笔者先说明一下自身的情况&#xff0c;怎么连接都连不上&#xff0c;网上的教程全部都看了一遍&#xff0c;基本上没用得上的&#xff0c;这篇文章里面的解决方案包括了笔者能在网上找到了最全面的办法总结&#xff0c;最后终于是连上了 目录 一.连接Jedis出错…

Linux初学(十一)中间件

一、web服务 1.1 中间件简介 中间件其实就是一类软件&#xff0c;中间件的作用是让用户可以看到一个网页 总结&#xff1a;客户端可以向服务端发送请求&#xff0c;服务器端会通过中间件程序来接收请求&#xff0c;然后处理请求&#xff0c;最后将处理结果返回给客户端 1.2 中…

自动驾驶的世界模型:综述

自动驾驶的世界模型&#xff1a;综述 附赠自动驾驶学习资料和量产经验&#xff1a;链接 24年3月澳门大学和夏威夷大学的论文“World Models for Autonomous Driving: An Initial Survey”。 在快速发展的自动驾驶领域&#xff0c;准确预测未来事件并评估其影响的能力对安全性…

SQL面试题(1)连续登陆问题

​ 轻松一点&#xff0c;写一些SQL面试题系列&#xff0c;今天从连续登陆问题开始。连续登陆无疑是数据开发面试高频面试题&#xff0c;但遇到本人面试可能并不会出现这个面试题&#xff0c;一般我会根据实际开发场景出具SQL场景题目&#xff0c;且会设计成从浅入深考察应聘者的…