代码随想录第20天:二叉树part6|leetcode654最大二叉树|leetcode617合并二叉树|leetcode700二叉搜索树中的搜索|leetcode98验证二叉搜索树。

leetcode654:最大二叉树

文章讲解:leetcode654

leetcode617:合并二叉树

文章讲解:leetcode617

leetcode700:二叉搜索树中的搜索

文章讲解:leetcode700

leetcode98:验证二叉搜索树

文章讲解:leetcode98

目录

1,leetcode654 最大二叉树

2,leetcode617 合并二叉树

3,leetcode700 二叉搜索树中的搜索。

4,leetcode98 验证二叉搜索树

5,总结


1,leetcode654 最大二叉树

有了昨天的铺垫,这道题还是不难的。在最大处切就行。

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


        return root;
    }
};

卡了一下的地方在于构建right和left的区间,传入两个索引位置应该是左闭右开,left的结尾传入的是maxIndex,而不是maxIndex-1。

class Solution {
private:
    // 在左闭右开区间[left, right),构造二叉树
    TreeNode* traversal(vector<int>& nums, int left, int right) {
        if (left >= right) return nullptr;

        // 分割点下标:maxValueIndex
        int maxValueIndex = left;
        for (int i = left + 1; i < right; ++i) {
            if (nums[i] > nums[maxValueIndex]) maxValueIndex = i;
        }

        TreeNode* root = new TreeNode(nums[maxValueIndex]);

        // 左闭右开:[left, maxValueIndex)
        root->left = traversal(nums, left, maxValueIndex);

        // 左闭右开:[maxValueIndex + 1, right)
        root->right = traversal(nums, maxValueIndex + 1, right);

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

代码随想录的这个代码就避免了每次递归创建两个vector的消耗。

2,leetcode617 合并二叉树

这道题是操作两棵树,意味着在遍历过程中两棵树要同步。题目中有一点需要注意,就是如果一个是null,另一个不是,就返回那个不是的。因此其实真正需要遍历的是两个数的公共部分,不公共的部分只需要返回不是空的那颗子树即可:

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

拿下。

3,leetcode700 二叉搜索树中的搜索。

数据结构的常规操作了:

递归:

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

迭代:

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

bst节点的遍历很有规律,因此很简单。

4,leetcode98 验证二叉搜索树

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

这道题的定义完全就是递归定义,因此递归判断一下即可。

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        if(root == nullptr) return true;
        if(root->left&&root->left->val>=root->val||root->right&&root->right->val<=root->val)return false;
        return isValidBST(root->left)&&isValidBST(root->right);
    }
};//卡了一个测试用例

在70多的时候卡住了。

  • 陷阱1

不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了

确实,应该是左边全部小于中间,右边全部大于中间才行。

class Solution {
public:
    vector<int> nums;
    void traverse(TreeNode* node){
        if(node == nullptr)return;
        traverse(node->left);
        nums.push_back(node->val);
        traverse(node->right);
    }
    bool isValidBST(TreeNode* root) {
        traverse(root);
        for(int i = 0;i<nums.size()-1;i++){
            if(nums[i]>=nums[i+1])return false;
        }
        return true;
    }
};

转化成中序遍历,再检查是否有序,就可以了。

5,总结

经过几天二叉树刷题,感觉渐入佳境,递归写的越来越熟练了。以前不敢写的现在也敢写了。在训练营中的坚持确实是有用的。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值