当前位置: 首页 > news >正文

算法day16|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

算法day16|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

  • 654.最大二叉树
  • 617.合并二叉树
    • 1.额外申请空间(失败)
    • 2.不额外申请空间
  • 700.二叉搜索树中的搜索
  • 98.验证二叉搜索树
    • 1.遍历后排序
    • 2.边遍历遍排序
    • 3.指针记录法

654.最大二叉树

这道题很简单,其实就是105、106的变式题。具体代码如下:

class Solution {
public:TreeNode*traversal(vector<int>& nums){if(nums.empty())return nullptr;int max=nums[0];int index=0;for(int i=1;i<nums.size();i++){if(nums[i]>max){max=nums[i];index=i;} }TreeNode*root=new TreeNode(max);if(nums.size()==1)return root;vector<int> leftNums(nums.begin(),nums.begin()+index);vector<int> rightNums(nums.begin()+index+1,nums.end());root->left=traversal(leftNums);root->right=traversal(rightNums);return root;}TreeNode* constructMaximumBinaryTree(vector<int>& nums) {if(!nums.empty())return traversal(nums);elsereturn nullptr;}
};

总体思路与105、106类似,甚至更简单。

617.合并二叉树

1.额外申请空间(失败)

不知道为什么运行不了…,代码如下:

class Solution {
public:TreeNode* traversal(TreeNode* root1, TreeNode* root2){if(root1==nullptr&&root2==nullptr)return nullptr;TreeNode*root=new TreeNode();if(root1!=nullptr&&root2!=nullptr)root->val=root1->val+root2->val;else if(root1==nullptr&&root2!=nullptr)root->val=root2->val;else if(root1!=nullptr&&root2==nullptr)root->val=root1->val;root->left=traversal(root1->left,root2->left);root->right=traversal(root1->right,root2->right);return root;}TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {return traversal(root1,root2);}
};

2.不额外申请空间

class Solution {
public:
TreeNode* traversal(TreeNode* root1, TreeNode* root2){if(!root1&&!root2)return nullptr;else if(!root1)return root2;else if(!root2)return root1;else{root1->val+=root2->val;}root1->left=traversal(root1->left,root2->left);root1->right=traversal(root1->right,root2->right);return root1;}TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {return traversal(root1,root2);}
};

直接在root1上进行操作,不用额外申请空间。

700.二叉搜索树中的搜索

class Solution {
public:TreeNode* traversal(TreeNode* root, int val){if(root==nullptr)return nullptr;if(root->val>val)return traversal(root->left,val);if(root->val<val)return traversal(root->right,val);elsereturn root;}TreeNode* searchBST(TreeNode* root, int val) {return traversal(root,val);}
};

要注意一下BST的特点:BST首先得是二叉平衡树,满足左<中<右。所以:

if(root->val>val)return traversal(root->left,val);if(root->val<val)return traversal(root->right,val);

另外,如果递归有返回值的话,在单层递归里面肯定是需要设置变量来接收的,或者直接return 递归。

98.验证二叉搜索树

1.遍历后排序

class Solution {
public:void traversal(TreeNode* root,vector<int> &vec){if(root==nullptr)return ;traversal(root->left,vec);vec.push_back(root->val);traversal(root->right,vec);}bool isValidBST(TreeNode* root) {if(root==nullptr)return true;else{vector<int> vec;traversal(root,vec);for(int i=0;i<vec.size()-1;i++){if(vec[i]>=vec[i+1])return false;}return true;}}
};

这题的易错点就是必须保证左子树上的所有元素都要小于根节点,右子树同理,而不是仅仅是单个左孩子结点或者右孩子结点。这样的思路用递归就很难实现了。

所以我们另辟蹊径,利用二叉搜索树的最重要的特征之一:中序序列单调递增 。我们只需要用数组收集中序序列,然后去判断它是否递增即可。

2.边遍历遍排序

对于递增的判断其实是可以在遍历过程中就实现的,代码如下:

class Solution {
public:long long MaxValue = LONG_MIN;bool traversal(TreeNode* root){if(root==nullptr)return true;bool left=traversal(root->left);if(root->val>MaxValue)MaxValue=root->val;elsereturn false; bool right=traversal(root->right);return left&&right;}bool isValidBST(TreeNode* root) {return traversal(root);}
};

为了判断中序序列是否递增,我们需要一个值来继承之前结点的大小,然后与当前结点比较即可。由于力扣中输入了Int的最小值,所以我们采用long long型的最小值来接受第一个元素,十分巧妙:

		long long MaxValue = LONG_MIN;if(root->val>MaxValue)MaxValue=root->val;elsereturn false;

这样就可以保证第一个数的顺利进行。因为不想for循环,递归的时候是很难定位到第几个元素的,所以想把第哪个元素赋值为几,这是做不到的。只有在深刻理解逻辑之后做一些巧思。

3.指针记录法

class Solution {
public:TreeNode*pre=nullptr;bool traversal(TreeNode* root){if(root==nullptr)return true;bool left=traversal(root->left);if(pre!=nullptr&&pre->val>=root->val)return false;elsepre=root;bool right=traversal(root->right);return left&&right;}bool isValidBST(TreeNode* root) {return traversal(root);}
};

我们改用指针来记录,实现一个更巧妙的逻辑:用指针记录前面的值,只有当指针的值大于当前的值时,return false。问题在于,指针该如何记录呢?逻辑很巧妙,因为记录第一个值是非常关键的。初始时,我们设pre为null,第一次就是因为pre为null,成功赋值;其他时候是因为满足排序,所以成功赋值。它们的逻辑是有区别的。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • filezilla使用教程(window下filezilla使用教程)
  • 梧桐数据库(WuTongDB):什么是“顺序扫描”
  • [GESP202312 四级] 田忌赛马
  • 今日算法:蓝桥杯基础题之“星系炸弹”
  • 掌握 Python列表:从基础到进阶技巧
  • FutureTask通常如何使用?
  • Ethercat设备数据 转IEC61850项目案例
  • django学生就业管理系统—计算机毕业设计源码24237
  • ★ 算法OJ题 ★ 力扣11 - 盛水最多的容器
  • qtlinux
  • MySQL中的COALESCE()函数用法,返回第一个非 NULL 的参数
  • 什么是数字人
  • How to install mysql 5.7 with podman in Ubuntu 24.04
  • CMake基本语法大全
  • c++同人小游戏之斗罗大陆4
  • canvas 五子棋游戏
  • Cumulo 的 ClojureScript 模块已经成型
  • HashMap剖析之内部结构
  • idea + plantuml 画流程图
  • IOS评论框不贴底(ios12新bug)
  • java中具有继承关系的类及其对象初始化顺序
  • JSDuck 与 AngularJS 融合技巧
  • mockjs让前端开发独立于后端
  • nfs客户端进程变D,延伸linux的lock
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • PHP 的 SAPI 是个什么东西
  • PHP那些事儿
  • Sass 快速入门教程
  • TypeScript实现数据结构(一)栈,队列,链表
  • ucore操作系统实验笔记 - 重新理解中断
  • 程序员最讨厌的9句话,你可有补充?
  • 服务器从安装到部署全过程(二)
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 三栏布局总结
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 白色的风信子
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (论文阅读30/100)Convolutional Pose Machines
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (贪心) LeetCode 45. 跳跃游戏 II
  • (一)Linux+Windows下安装ffmpeg
  • (一)Neo4j下载安装以及初次使用
  • (译)2019年前端性能优化清单 — 下篇
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .NET C# 使用 iText 生成PDF
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .Net MVC4 上传大文件,并保存表单
  • .Net插件开发开源框架
  • /deep/和 >>>以及 ::v-deep 三者的区别