代码随想录算法训练营29期Day20|LeetCode 654,617,700,98

2024-01-15 07:12

本文主要是介绍代码随想录算法训练营29期Day20|LeetCode 654,617,700,98,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

   文档讲解:最大二叉树  合并二叉树  二叉搜索树中的搜索  验证二叉搜索树

654.最大二叉树

题目链接:https://leetcode.cn/problems/maximum-binary-tree/description/

思路:

        本题目要求我们根据已知数组构建一颗最大二叉树,最大值为根节点,最大值左边区间构建左子树,最大值右边区间构建右子树。

        很容易我们就能想到这道题目要用递归来实现,因为针对每个区间我们的操作都是相同的:先寻找最大值构建根节点,再分割左右区间构建左右子树。因此我们对总区间 [0,n-1] 进行递归处理,递归边界条件为 l==r-1 ,即区间中只有一个点,这时就到达了叶子节点,不用再向下构建了,挨层回溯子树根节点即可,最后总区间回溯出的节点就是整颗树的根节点。

核心代码:

/*** 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 {
private:TreeNode* createTree(vector<int>& nums,int l,int r){if(l>=r||l<0||r>nums.size()) return NULL;int maxval=l;for(int i=l;i<r;i++)if(nums[i]>nums[maxval]) maxval=i;TreeNode* cur=new TreeNode(nums[maxval]);cur->left=createTree(nums,l,maxval);cur->right=createTree(nums,maxval+1,r);return cur;}
public:TreeNode* constructMaximumBinaryTree(vector<int>& nums) {return createTree(nums,0,nums.size());}
};

617.合并二叉树

题目链接:https://leetcode.cn/problems/merge-two-binary-trees/description/

思路:

        本题要求我们将两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

        我们从根节点开始,考虑每个节点的情况,分别处理即可,分析以后会发现很简单。

        我们先假设两棵树为树1和树2,当前处理到的位置相同的点为cur1和cur2,其中cur1为树1的节点,cur2为树2的节点。下面我们分类讨论:

        1.如果cur1和cur2都是空节点,那么新树中这个点必定为空,就不用向下处理了,向下肯定也是空的,因为下面已经没有点了。

        2.如果cur1是空节点,cur2不是空节点,那么新树中以当前位置这个点为根节点的子树,其构造必定和树2中以cur2为根节点的子树完全一致,因为cur1是空的,那么树1以cur1为根节点的子树也必定为空,那就不会向cur2那颗子树合并,或者说合并后还是cur2那颗子树,所以我们返回cur2即可,也不必再向下构造了。

        3.如果cur1不是空节点,cur2是空节点,那么这种情况与2重复,同样的处理方式即可,不过这次返回的是cur1这棵子树,或者说树1的cur1节点。

        4.如果cur1和cur2都不是空节点,那么我们将其值合并,变成新节点赋给新树对应位置节点,然后分别递归处理左右儿子,左右儿子的情况又回到这四种情况中,判断是哪种情况处理即可。

核心代码:

/*** 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 {TreeNode* merge(TreeNode* cur1,TreeNode* cur2){if(!cur1&&!cur2) return NULL;if(!cur1) return cur2;if(!cur2) return cur1;cur1->val+=cur2->val;cur1->left=merge(cur1->left,cur2->left);cur1->right=merge(cur1->right,cur2->right);return cur1;}
public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {return merge(root1,root2);}
};

700.二叉搜索树中的搜索

题目链接:https://leetcode.cn/problems/search-in-a-binary-search-tree/description/

思路:

       本题要求我们在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

        思路也很简单,递归向下搜索即可。每次判断当前节点的值与val的大小关系,如果val大,就向右子树去搜,如果val小,就向左子树去搜,搜到空节点或者值相等为止。值相等证明找到了,返回当前节点,空节点证明树中没有该值,返回空即可。

核心代码:

/*** 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 {
private:TreeNode* searchval(TreeNode* cur,int val){if(!cur) return NULL;else if(cur->val==val) return cur;else if(cur->val>val) return searchval(cur->left,val);else return searchval(cur->right,val);}
public:TreeNode* searchBST(TreeNode* root, int val) {return searchval(root,val);}
};

98.验证二叉搜索树

题目链接:https://leetcode.cn/problems/validate-binary-search-tree/description/

思路:

        本题目要求我们判断一棵树是否是一个有效的二叉搜索树。

        首先我们要知道,所谓的有效的二叉搜索树,就是说针对树中任意非空节点作为根节点来说,左子树的最大值小于根节点值,右子树的最小值大于根节点值。因此我们从根节点开始递归的处理每棵子树即可。

        我们可以开一个全局变量flag,记录整颗树是否合法。也就是递归的时候处理到不合法情况让flag值为false即可。递归结束后flag为true证明整颗树合法,反之则不合法。flag初始值为true。

        每层递归我们要做的事情如下:递归处理左子树的最大值和最小值,递归处理右子树的最大值和最小值。得到这四个值结合根节点值我们就可以判断整颗树是否合法,从而决定flag是否为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 {
private:bool flag=true;vector<int> isValid(TreeNode* cur){vector<int> nums;int minnum=cur->val,maxnum=cur->val;if(cur->left){vector<int> numl=isValid(cur->left);if(numl[0]<minnum) minnum=numl[0];if(numl[1]>maxnum) maxnum=numl[1];if(numl[1]>=cur->val){flag=false;}}if(cur->right){vector<int> numr=isValid(cur->right);if(numr[0]<minnum) minnum=numr[0];if(numr[1]>maxnum) maxnum=numr[1];if(numr[0]<=cur->val){flag=false;}}nums.push_back(minnum);nums.push_back(maxnum);return nums;}
public:bool isValidBST(TreeNode* root) {isValid(root);return flag;}
};

今日总结

        今日学习时长2h,题目不算难,但我的解法不算好,肯定有更好的解法,还没来得及看,因为这两天又要准备期末,先把期末过了再说。

这篇关于代码随想录算法训练营29期Day20|LeetCode 654,617,700,98的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/608063

相关文章

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Python屏幕抓取和录制的详细代码示例

《Python屏幕抓取和录制的详细代码示例》随着现代计算机性能的提高和网络速度的加快,越来越多的用户需要对他们的屏幕进行录制,:本文主要介绍Python屏幕抓取和录制的相关资料,需要的朋友可以参考... 目录一、常用 python 屏幕抓取库二、pyautogui 截屏示例三、mss 高性能截图四、Pill

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave