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

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

思路:

        构建二叉树一般都使用前序遍历的方式,先构建根节点,然后构建左右子树 

        先要确定递归函数返回值和参数,之后确定终止条件,最后是单层的递归逻辑。

代码:

class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        //前序遍历构建二叉树
        //1.递归函数的参数和返回值:返回根节点所以是TreeNode*,参数是不断划分的数组
        //2.终止条件,数组里只有一个元素,说明遍历到了叶子节点
        if(nums.size() == 1){
            TreeNode* node = new TreeNode(0);
            node->val = nums[0];
            return node;
        }
        //3.单层递归逻辑
        
        //找到数组中的最大值和最大值下标
        int MaxValue = 0;
        int MaxIndex = 0;
        for(int i = 0; i < nums.size(); i++){//中
            if(nums[i] > MaxValue){
                MaxValue = nums[i];
                MaxIndex = i;
            }
        }
        //根据最大值建立根节点
        TreeNode* node = new TreeNode(0);
        node->val = MaxValue;

        //根据最大值下标分割左右数组建立左右子树,数组区间左闭右开
        //左数组,[0, MaxIndex),构建左子树
        if(MaxIndex > 0){//左
            vector<int> leftvec(nums.begin(), nums.begin() + MaxIndex);
            node->left = constructMaximumBinaryTree(leftvec);
        }
        //右数组,[MaxIndex + 1, end),构建右子树
        if(MaxIndex < nums.size() - 1){//右
            vector<int> rightvec(nums.begin() + MaxIndex + 1, nums.end());
            node->right = constructMaximumBinaryTree(rightvec);
        }

        return node;
    }
};

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

思路:

         1、递归参数和返回值:因为要合并两颗二叉树,参数是两颗二叉树的根节点,返回值是合并后的二叉树根节点

         2、终止条件:任意一颗二叉树遍历到空节点,直接返回另一颗树的根节点。

         3、单层递归逻辑:根节点的值直接相加,然后递归合并两颗二叉树的左子树和右子树。

代码:

class Solution {
public:
    //前序遍历合并
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        //终止条件:1.root1和root2一起遍历,当root1遍历到空节点,root2不为空,返回以root2为节点的子树 2.当root2遍历到空节点,root1不为空,返回以root1为节点的子树
        if(root1 == NULL) return root2;
        if(root2 == NULL) return root1;

        //单层递归逻辑
        TreeNode* node = new TreeNode(0);
        node->val = root1->val + root2->val;//中
        
        node->left = mergeTrees(root1->left, root2->left);//左
        node->right = mergeTrees(root1->right, root2->right);//右

        return node;

    }
};

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

思路:

        二叉搜索树:若左子树不为空,其左子树上的所有节点的值都小于根节点的值;若右子树不为空,其右子树上的所有节点的值都大于根节点的值;它的左右子树也是二叉搜索树。

 在单层递归逻辑里需要注意:因为它是有序的,搜索时需要对比根节点的值和目标值来判断是遍历左子树还是右子树。

代码:

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        //终止条件:遍历到空节点或者节点值和目标值相等
        if(root == NULL) return NULL;
        if(root->val == val) return root;、

        //左右子树如果搜索到了val,要将该节点返回。所以需要定义一个变量result来接住递归函数的返回值
        TreeNode* result = NULL;
        if(val < root->val){
            result = searchBST(root->left, val);
        }
        if(val > root->val){
            result = searchBST(root->right, val);
        }
        return result;
    }
};

非递归实现:

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

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

思路:

       验证二叉搜索树需要使用中序遍历左中右的顺序

方法一:使用中序遍历得到的是一个递增的序列,那么定义一个数组收集中序遍历的元素,然后再判断这个数组是否递增,注意二叉搜索树中元素不允许重复。

代码:

class Solution {
public:
    vector<int> vec;
    //中序遍历收集元素
    void traversal(TreeNode* cur){
        if(cur == NULL) return;
        traversal(cur->left);
        vec.push_back(cur->val);
        traversal(cur->right);
    }   
    bool isValidBST(TreeNode* root) {
        vec.clear();
        if(root == NULL) return true;
        traversal(root);
        //判断数组中元素是否递增
        for(int i = 1; i < vec.size(); i++){
            if(vec[i - 1] >= vec[i]) return false;
        }
        return true;
    }
};

 方法二:双指针,一个pre记录前一个节点的值,一个cur记录当前节点的值,如果中序遍历的时候始终保持cur->val > pre->val,说明是一颗二叉搜索树;

代码:

class Solution {
public:
    TreeNode* pre = NULL;//全局变量,不断更新指向前一个节点的指针
    bool isValidBST(TreeNode* root) {
       if(root == NULL) return true;
       bool left = isValidBST(root->left);//左
        //如果前一个节点的值大于等于当前节点的值,直接返回false;否则,就更新前一个节点,让其指向当前节点
       if(pre != NULL && pre->val >= root->val){
           return false;
       }else{
           pre = root;//记录前一个节点
       }
       bool right = isValidBST(root->right);//右

       return left && right;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值