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

654. 最大二叉树 - 力扣(LeetCode)https://leetcode.cn/problems/maximum-binary-tree/最大二叉树的解题思路和上一期我们做的中后序构造二叉树解题思路差不多,不同的是这道题只给我们一个数组,让我们在数组中找出大数当节点,为什么说和构造二叉树那道题差不多呢?是因为我们在构造二叉树的时候的思路就是在数组中找到最大节点,然后分成左右部分,进入·下一层递归,如此往复得到最大二叉树。

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

与上一道构造二叉树,不同之处大概只有在一个数组里操作而已。如果那一道题可以做的出来话,这道题应该会容易一些。


617. 合并二叉树 - 力扣(LeetCode)https://leetcode.cn/problems/merge-two-binary-trees/合并二叉树是考察我们如何一次控制两个二叉树的题,题目思路并不难,就是将两个二叉树都有的节点将它们的值合并在一起组成新节点,如果只有一个有那么就将那一个直接拿过来就可以了,我们可以直接在第一个或者第二个树直接合并,相当于取长补短的思路,也可以创建一个新的树在上面合并两个二叉树,两种思路都可行且代码简单。

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

这里只给出第一种思路,即将合并好的二叉树放在第一棵树上并将其返回,但是题目思路简单,想用递归实现我觉得是没那么容易的,我第一次做的时候递归的结束判断条件想不出来。这里的递归结束就是判断1如果第一棵树当前对应节点没有,那就返回第二个对应节点,如果第二个没有那就返回第一个,如果两个都没有那么返回的其中一个也就是null。


700. 二叉搜索树中的搜索 - 力扣(LeetCode)https://leetcode.cn/problems/search-in-a-binary-search-tree/二叉树的搜索是考察对于二叉搜索树的特性的使用,当然使用暴力搜索忽略其特性应该也能做得出来。

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

这道递归里最重要的部分,仍然是要想通递归的结束条件判断,如果走到空了那就往上返回,该侧子树目前为空,再遍历另一侧如果仍然是空那就返回了空,如果在某一侧找到了节点,则向上返回当前的节点root,注意:如果找到了则会直接返回,当前是root2=找到的节点,第二个向右递归是进不去的直接返回了这点不用担心,而且这里也体现出了为什么我们最开始要创立一个root2它的目的就是接收返回值的,接收到返回值才能将节点所在处正确的返回。其次是单层递归的逻辑,这里我们充分使用了二叉搜索树的特性,即二叉搜索树的左子树所有节点比根节点都要小,而且右子树比根节点数值都要大,利用这一特点,我们就可以有方向的进行搜索,判断当前节点与目标值val的大小比较。


98. 验证二叉搜索树 - 力扣(LeetCode)https://leetcode.cn/problems/validate-binary-search-tree/验证二叉搜索树仍然是考察搜索树的特性,按照搜索树的特性来写代码,但是也有一些需要注意的点写在下方。

class Solution {
public:
long long pre=LONG_MIN;
    bool isValidBST(TreeNode* root) {
        if(root==NULL)return true;//二叉树也可以为空
        bool left=isValidBST(root->left);
        if(pre<root->val)pre=root->val;
        else return false;
        bool right=isValidBST(root->right);
        return left&&right;
    }
};

第一点是递归思路对于我来说反正是不好想的,这里要注意在里面创建两个布尔类型的用途,其次是第一句判断结束并不是可有可无的,没有一定会超时,,它的作用是将两个布尔类型赋成true,它并不是像有些递归条件里的走到叶子节点返回上一层,那样的题可能由于逻辑代码中存在指针不为空才能进入递归的判断,显得可有可无,但本题它的用处并非这样。再者逻辑判断代码也很重要·,一开始很多人可能会把代码写成判断该节点的数值比左节点大且比右节点小就直接判断是true,这是错误的,因为我们要判断的是比它的左子树小,右子树大,而不是单纯比较比某节点的大小,所以这道题的思路一定要选用中序遍历,使它能够直接从下面进行遍历,从下往上走就可以知道下面的子树符不符合搜索的规范了。整体来看坑很多需要注意。


以上代码均可ac。顺便说一句,二叉搜索树的大多数判断类型题,都可以采用中序遍历放到一个数组中然后去操作数组比较其中数据的大小来完成对应的题目判断。因为中序遍历是一个递增的序列。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习算法的杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值