Day|20 leetcode 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

leetcode 654.最大二叉树

题目链接:654. 最大二叉树 - 力扣(LeetCode)

视频链接:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili

题目概述:

给定一个不重复的整数数组构建最大二叉树,构建规则如下:

1.根节点是最大值。
2.在最大值左边的数用来构建左子树。
3.在最大值右边的数用来构建右子树。

示例 1:


输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]

思路

像构造二叉树这种题,一般用前序(中左右),因为要先构造中间节点,然后在构造左子树和右子树。本题依旧按照递归三部曲走,首先确定递归函数的参数和返回值,其次确定终止条件,最后确定单层递归逻辑。最大二叉树构建过程如图所示:

·还需要注意区间,不要一会左闭右开 ,一会左闭右闭的!!

代码实现(左闭右开)
class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        TreeNode* node = new TreeNode(0);
        if (nums.size() == 1) {
            node->val = nums[0];
            return node;
        }

        int maxValue = 0;
        int maxValueIndex = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] > maxValue) {
                maxValue = nums[i];
                maxValueIndex = i;
            }
        }
        node->val = maxValue;

        if (maxValueIndex > 0) {
            vector<int> newVec(nums.begin(), nums.begin() + maxValueIndex);
            node->left = constructMaximumBinaryTree(newVec);
        }

        if (maxValueIndex < (nums.size() - 1)) {
            vector<int> newVec(nums.begin() + maxValueIndex + 1, nums.end());
            node->right = constructMaximumBinaryTree(newVec);
        }
        return node;
    }
};

leetcode 617.合并二叉树

题目链接:617. 合并二叉树 - 力扣(LeetCode)

视频链接:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili

题目概述:

给你两棵二叉树:

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会),如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值,否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

示例 1:


输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

 ·注意: 合并过程必须从两个树的根节点开始。

思路

本题其实用哪种遍历方式都行(前中后都可以)。我们可以不用去定义一个新的树,用给的树1就可以,在树1的基础上加树2,这样最后就会变成一个合并好的新树,定义一个新的树也行,只不过会多加那么一丢丢代码。以前序为例,合并二叉树的过程,如图所示:

代码实现
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1 == NULL) return root2;
        if(root2 == NULL) return root1;
        root1->val += root2->val;
        root1->left = mergeTrees(root1->left,root2->left);
        root1->right = mergeTrees(root1->right,root2->right);
        return root1;

    }
};

leetcode 700.二叉搜索树中的搜索

题目链接:700. 二叉搜索树中的搜索 - 力扣(LeetCode)

视频链接:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索_哔哩哔哩_bilibili

题目概述:

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。

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

示例 1:

输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

思路

做这道题之前,我们要知道什么是二叉搜索树,二叉搜索树满足它的根节点要比左子树里所有数都,比右子树里所有数都小,当然了这在左右子树里依旧符合这个规则。所以说这道题不用去考虑顺序问题,因为二叉搜索树本身已经给了我们顺序。也正是因为二叉搜索树的有序性,也会使代码变得出乎意外的简单。

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

leetcode 98.验证二叉搜索树

题目链接:98. 验证二叉搜索树 - 力扣(LeetCode)

视频链接:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树_哔哩哔哩_bilibili

题目概述:

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

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

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:


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

思路

验证二叉搜索树最直白的想法就是把这棵树变成一个数组,然后比较大小,要注意的是二叉搜索树中元素不能有重复的。这道题还需要注意的是不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。如图所示:

二叉搜索树

·这就不是棵二叉搜索树了! !

其实本题也可以用双指针法来进行优化(可以避免初始化最小值),定义一个指针,用它来记录前一个结点,然后比大小就行了。

代码实现

要知道根节点是空的话,它既是二叉搜索树,也是平衡二叉树,它啥树都是。

class Solution {
public:
    TreeNode* pre = NULL; // 用来记录前一个节点
    bool isValidBST(TreeNode* root) {
        if (root == NULL) return true;
        bool left = isValidBST(root->left);

        if (pre != NULL && pre->val >= root->val) return false;
        pre = root; // 记录前一个节点

        bool right = isValidBST(root->right);
        return left && right;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值