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

654.最大二叉树

力扣

和前序+中序构造二叉树类似,按照题目要求走即可。重点是如何优化:

注意类似用数组构造二叉树的题目,每次分隔尽量不要定义新的数组,而是通过下标索引直接在原数组上操作,这样可以节约时间和空间上的开销。

class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector& nums) {
        return traversal(nums, 0, nums.size()); //注意左闭右开!right = nums.size()
    }

    TreeNode* traversal(vector& nums, int left, int right){
        if(left >= right) return nullptr; //递归结束(相当于nums.size() == 0)

        //find max
        int max = INT_MIN;
        int maxIndex = 0;
        for(int i = left; i < right; i++){
            if(nums[i] > max){
                max = nums[i];
                maxIndex = i;
            }
        }

        TreeNode* root = new TreeNode(max);

        //切割(参数为分隔的index) + 递归
        //注意是左闭右开!
        root->left = traversal(nums, left, maxIndex); 
        //注意此时right就是maxIndex,不用加东西

        root->right = traversal(nums, maxIndex+1, right);
        return root;
    }
};

 

 

617.合并二叉树(递归)

力扣 

遵循递归三部曲(终止条件 + 更新变量 + 递归)即可,见递归个人总结。

注意:假设都merge到root1上,所以所有递归都统一root1。其实root2也行,统一就行

TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
    //终止条件
    if(root1 == nullptr) return root2; //即都已合并到了root2
    if(root2 == nullptr) return root1;

    //假设都合并到root1上
    //更新变量
    root1->val = root1->val + root2->val;

    //递归
    root1->left = mergeTrees(root1->left, root2->left);
    root1->right = mergeTrees(root1->right, root2->right);
    return root1;
}

 

700.二叉搜索树中的搜索

力扣

主要是利用二叉树的特性,左小右大。

递归:

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        //终止条件 - 找完了还没找到
        if(root == nullptr) return nullptr;

        if(val < root->val){
            //to left
            return searchBST(root->left, val); //注意这里要return
        } else if (val > root->val){
            return searchBST(root->right, val);
        }
        //如果能进行到这里就是找到了,因为18-22的都会return
        return root;
    }
};

迭代:

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        while(root != nullptr){
            if(val < root->val){
                root = root->left;
            } else if (val > root->val){
                root = root->right;
            } else {
                return root;
            }
        }
        
        //不存在这个值
        return nullptr;
    }
};

 

 

 

98.验证二叉搜索树

力扣

不能单纯对每一个节点查是否左小右大,因为可能会有这种情况

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

思路:中序遍历为升序

如果用vector记录,就另写一个traversal function,进行中序遍历并push到vector中,然后查vector是不是升序的。

优化的思路:直接在每一步记录当前value,比较是否为升序,不再建立vector

class Solution {
public:
    vector vect;
    long long maxValue = LONG_MIN; //!本题不能写INT_MIN,测试案例会卡

    //中序遍历为升序 - 优化:直接在每一步看是否为升序,不再建立vector
    bool isValidBST(TreeNode* root) {
        if(root == nullptr) return true;
        bool left = isValidBST(root->left);
        //记录当前node的值,看是否是一直在增加的
        if(maxValue < root->val){
            maxValue = root->val;
        } else {
            return false;
        }

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

二刷关注一下迭代 & 用min和max的写法 

你可能感兴趣的:(算法,leetcode,c++,数据结构)