Bootstrap

代码随想录算法训练营第二十天| LeetCode 654.最大二叉树 、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

一、LeetCode 654.最大二叉树

状态:已解决

1.思路 

        这道题其实跟上周做的构造二叉树有点像,无非就处理中间节点、然后递归构建左子树、右子树,由于要构造左右子树,并将左右子树的根节点返回给中间节点,因此只能前序遍历(原则上将也可以换个顺序,只是要多定义变量保存左右子树的地址而已)这道题中间节点的处理逻辑主要是求现在区间最大值所在索引位置,然后将该节点的值作为新的树的根节点,然后将分割得到的两个小区间作为左子树区间和右子树区间递归下去。

2.代码实现

class Solution {
public:
    TreeNode* construct(vector<int>& nums,int left,int right){//固定区间范围为左闭右开区间
        if(left>=right) return nullptr;//由左闭右开决定。

        //求分割点下标
        int maxValue = -1;
        int maxValueIndex = -1;
        for(int i=left;i<right;i++){
            if(nums[i] > maxValue){
                maxValue = nums[i];
                maxValueIndex = i;
            }
        }
        //构造中间节点
        TreeNode* root = new TreeNode(maxValue);

        //开始构造左子树
        root->left = construct(nums,left,maxValueIndex);//左闭右开决定的范围

        //构造右子树
        root->right = construct(nums,maxValueIndex+1,right);//左闭右开决定的范围

        return root;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return construct(nums,0,nums.size());
    }
};

 二、617.合并二叉树 

题目链接/文章讲解/视频讲解:https://programmercarl.com/0617.%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91.html

状态:已解决

1.思路

         其实这道题就是要我们同时操控两棵二叉树而已,因此只需要同时递归两棵树,两棵树的节点就可以处于对应位置。如果递归到某个时刻,一个树空了,就直接返回另一个树的节点指针即可。可以在root1的基础上加root2的值并返回root1,也可以在root2的基础上加root1的值并返回roott。

2.代码实现

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

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

        return root1;
    }
};

三、700.二叉搜索树中的搜索

题目链接/文章讲解/视频讲解:https://programmercarl.com/0700.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%90%9C%E7%B4%A2.html

状态:已解决

1.思路

        这道题比传统的搜索题简单很多,因为题目给的已经是排好序的二叉搜索树了,因此只需我们完成迭代操作即可:

        (1)目标值等于根节点的值,返回节点。

        (2)目标值小于根节点的值,遍历左子树。

        (3)目标值大于根节点的值,遍历右子树。

2.代码实现

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if(root == NULL) return root;
        TreeNode * result = NULL;
        if(root->val == val) return root;//返回根节点
        else if(root->val > val){
            result = searchBST(root->left,val);//遍历左子树
        }
        else{
            result = searchBST(root->right,val);//遍历右子树
        }
        return result;
    }
};

四、98.验证二叉搜索树

题目链接/文章讲解/视频讲解:https://programmercarl.com/0617.%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91.html

状态:已解决

1.思路 

         好吧其中这道题我刚开始没有很明确的思路,是看了老师讲解后才恍然大悟,原来可以先根据中序遍历将整棵树存入数组中,然后再检验整个数组是否是递增的,如果递增则代表原二叉树是一棵二叉搜索树。

        原理很简单,既然是中序遍历且数组递增,那就代表整棵树从左往右的值都是递增的,也就说明左中右是按照严格递增顺序排列的->即二叉搜索树。

2.代码实现

        原理知道,代码也就好写了,只是需要单开一个数组保存树的节点值。验证数组递增可以根据前一个元素值是否都小于后一个节点值来检验。

class Solution {
public:
    vector<int> s;
    void traversal(TreeNode* node){
        if(node == NULL) return ;
        traversal(node->left);//左
        s.push_back(node->val);//数值入栈
        traversal(node->right);//右
    }
    bool isValidBST(TreeNode* root) {
        traversal(root);
        bool result = true;
        for(int i=1;i<s.size();i++){
            if(s[i-1]>=s[i]) return false;
        }
        return true;
    }
};

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;