day20第六章二叉树(二刷)

今日任务

  • 654.最大二叉树
  • 617.合并二叉树
  • 700.二叉搜索树中的搜索
  • 98.验证二叉搜索树

654.最大二叉树

题目链接:

https://leetcode.cn/problems/maximum-binary-tree/description/

题目描述:

给定一个不重复的整数数组 nums最大二叉树 可以用下面的算法从 nums 递归地构建:

  1. 创建一个根节点,其值为 nums 中的最大值。
  2. 递归地在最大值 左边子数组前缀上 构建左子树。
  3. 递归地在最大值 右边子数组后缀上 构建右子树。

返回 nums 构建的 最大二叉树

示例 1:

https://assets.leetcode.com/uploads/2020/12/24/tree1.jpg

输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
    - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
        - 空数组,无子节点。
        - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
            - 空数组,无子节点。
            - 只有一个元素,所以子节点是一个值为 1 的节点。
    - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
        - 只有一个元素,所以子节点是一个值为 0 的节点。
        - 空数组,无子节点。

示例 2:

https://assets.leetcode.com/uploads/2020/12/24/tree2.jpg

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

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000
  • nums 中的所有整数 互不相同

题解代码:

/**
 * 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:
    //二刷
    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> leftVec(nums.begin(), nums.begin()+maxValueIndex);//区间:左闭右开
            node->left = constructMaximumBinaryTree(leftVec);
        }
        //处理右
        if(maxValueIndex < nums.size()-1){
            vector<int> rightVec(nums.begin()+maxValueIndex+1, nums.end()); //区间:左闭右开原则
            node->right = constructMaximumBinaryTree(rightVec);
        }
        return node;
    }

    //一刷
    /*
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        //设计构建二叉树,我们用前序的方式
        TreeNode* resNode = new TreeNode(0);

        if(nums.size()==1){
            resNode->val = nums[0];
            return resNode;
        }
        //处理根
        int maxValue = 0; //假定 最大值 
        int index =  0; // 记录最大值的下标

        for(int i = 0; i < nums.size();i++){//遍历数组
            if(nums[i]>maxValue){ //如果遇到比我们假定的最大值更大的元素,则更新
                maxValue = nums[i];
                index = i;  //下标也要记得更新
            }
        }
        resNode->val = maxValue;

        //处理左
        if(index > 0){ //要保证左区间至少有一个元素,才有继续下去的必要
            vector<int> leftVec(nums.begin(), nums.begin()+index);//对于区间,我们始终坚持左闭右开的原则
            resNode->left = constructMaximumBinaryTree(leftVec); //去递归吧,构建左子树

        }

        //处理右
        if(index < nums.size()-1){// 要保证右区间至少有一个元素,才有继续 下去 的必要
            vector<int> rightVec(nums.begin()+index+1, nums.end());//对于区间,我们始终坚持左闭右开的原则
            resNode->right = constructMaximumBinaryTree(rightVec); //去递归,构建右子树
        }

        return resNode;

    }
    */
};

617.合并二叉树

题目链接:

https://leetcode.cn/problems/merge-two-binary-trees/description/

题目描述:

给你两棵二叉树: root1root2

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

返回合并后的二叉树。

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

示例 1:

https://assets.leetcode.com/uploads/2021/02/05/merge.jpg

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

示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]

提示:

  • 两棵树中的节点数目在范围 [0, 2000]
  • 104 <= Node.val <= 104

题解代码:

/**
 * 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:
    //二刷
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2){
        //处理树1为空树的情况
        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;
    }

    //一刷,递归法,操作两个树
    /*
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        //还是要造树,所以还是用前序
        if(root1 == NULL){
            return root2;
        }
        if(root2 == NULL){
            return root1;
        }

        //就在tree1上面做改动,不构建新树了
        root1->val += root2->val;

        root1->left = mergeTrees(root1->left, root2->left);
        root1->right = mergeTrees(root1->right, root2->right);

        return root1;

    }
    */
};

700.二叉搜索树中的搜索

题目链接:

https://leetcode.cn/problems/search-in-a-binary-search-tree/description/

题目描述:

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

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

示例 1:

https://assets.leetcode.com/uploads/2021/01/12/tree1.jpg

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

示例 2:

https://assets.leetcode.com/uploads/2021/01/12/tree2.jpg

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

提示:

  • 数中节点数在 [1, 5000] 范围内
  • 1 <= Node.val <= 107
  • root 是二叉搜索树
  • 1 <= val <= 107

题解代码:

/**
 * 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:
    //二刷
    TreeNode* searchBST(TreeNode* root, int val){
        //利用二叉搜索树本身特点 递归地搜索val
        if(root == NULL || root->val == val){
            return root;
        }
        TreeNode* resNode = NULL;
        if(val < root->val){
            resNode = searchBST(root->left, val);
        }
        if(val > root->val){
            resNode = searchBST(root->right, val);
        }
        return resNode;

    }

    //一刷
    /*
    TreeNode* searchBST(TreeNode* root, int val) {
        //二叉搜索树,左节点值比根节点值小,右比根大
        //递归法
        //递归终止条件
        if(root==NULL || root->val==val){
            return root;
        }

        TreeNode* resNode = NULL;

        if(val < root->val){
            resNode = searchBST(root->left, val);
        }

        if(val > root->val){
            resNode = searchBST(root->right,val);
        }

        return resNode;

    }
    */
};

98.验证二叉搜索树

题目链接:

https://leetcode.cn/problems/validate-binary-search-tree/description/

题目描述:

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

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

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

示例 1:

https://assets.leetcode.com/uploads/2020/12/01/tree1.jpg

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

示例 2:

https://assets.leetcode.com/uploads/2020/12/01/tree2.jpg

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

提示:

  • 树中节点数目范围在[1, 104]
  • 231 <= Node.val <= 231 - 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 {
public:
    //二刷: 递归法, 中序遍历
    TreeNode* pre = NULL; //记录当前节点地前一个节点
    bool isValidBST(TreeNode* root){
        if(root == NULL){
            return true;
        }
        bool IsLeft = isValidBST(root->left);//左
        //中
        if(pre != NULL && pre->val >= root->val){
            return false;
        }
        pre = root;
        //右
        bool IsRight = isValidBST(root->right);//右
        return IsLeft&&IsRight;
    }

    //一刷:递归法
    /*
    TreeNode* pre = NULL; //记录当前遍历节点的前一个结点
    bool isValidBST(TreeNode* root) {
        if(root == NULL){
            return true;   //空 便可是 万物
        }

        //二叉搜索树特点:左比根小,右比根大,中序遍历下来恰好是递增序列

        //中序

        //处理左
        bool leftIs = isValidBST(root->left);
        //处理中
        
        if(pre!=NULL && pre->val>=root->val){
            return false;
        }
        pre = root;
        //处理右
        bool rightIs = isValidBST(root->right);

        return leftIs&&rightIs;

    }
    */
};

总结

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值