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

Day20

654.最大二叉树

跟中序后序构造数组思路差不多,都是先建立根节点(寻找符合条件的数值),然后确定左右子树的范围。

一般情况来说:如果让空节点(空指针)进入递归,就不加if,如果不让空节点进入递归,就加if限制一下, 终止条件也会相应的调整。

class Solution {
public:
    TreeNode*   travelsal(vector<int>& nums,int left,int right){
        if(left==right) return NULL;

        int delimiter=left;
        for(int i=left;i<right;i++){
            if(nums[i]>nums[delimiter]) delimiter=i;
        }

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

        int leftleft=left;
        int leftright=delimiter;
        int rightleft=delimiter+1;
        int rightright=right;

        root->left=travelsal(nums,leftleft,leftright);
        root->right=travelsal(nums,rightleft,rightright);

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

617.合并二叉树

 合并二叉树本质上其实也是遍历,只不过是每次左右同时进行,还需要注意的一点是当其中一个二叉树(比如t1)的孩子为空的时候,最后合并完的部分一定是另一个子树的所有值,所以只需要将t2的孩子节点返回就行了,后面的那些就不用处理了(这也是为什么可以用层序遍历)

递归:

class Solution {
public:
    TreeNode* travelsal(TreeNode* t1,TreeNode* t2){
        if(t1==NULL) return t2;
        if(t2==NULL) return t1;

        if(t1!=NULL &&t2!=NULL){
            t1->val+=t2->val;
        }

        t1->left=travelsal(t1->left,t2->left);
        t1->right=travelsal(t1->right,t2->right);

        return t1;
    }
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        return travelsal(root1,root2);
    }
};

迭代法:层序遍历的思路

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1==NULL) return root2;
        if(root2==NULL) return root1; 
        queue<TreeNode*> que;
        que.push(root1);
        que.push(root2);
        while(!que.empty()){
            TreeNode* node1=que.front();
            que.pop();
            TreeNode* node2=que.front();
            que.pop();
            node1->val+=node2->val;

            if(node1->left!=NULL &&node2->left!=NULL){
                que.push(node1->left);
                que.push(node2->left);
            }
            if(node1->left==NULL){
                node1->left=node2->left;
            }
            if(node1->right!=NULL &&node2->right!= NULL){
                que.push(node1->right);
                que.push(node2->right);
            }
            if(node1->right==NULL){
                node1->right=node2->right;
            } 
        }
        return root1;
    }
};

700.二叉搜索树中的搜索

对于递归法,重点还是返回值怎么处理的问题,一个函数的返回值只是代表这个函数运行完之后的返回值(像本题,search的返回值需要确实是一个节点,但是需要用一个变量来表示,比如下面的result)。

class Solution {
public:
    TreeNode* search(TreeNode* root,int val){
        if(root==NULL) return NULL;

        TreeNode* result;
        if(root->val==val){
            return root;
        }
        else if(root->val>val){
            result=search(root->left,val);
        }
        else{
            result=search(root->right,val);
        }
        return result;
    }
    TreeNode* searchBST(TreeNode* root, int val) {
        return search(root,val);
    }
};

迭代法:

本题迭代法确实不需要队列和栈,(因为已经树有序了,所以只需要按照路径走就可以了),不需要搜索其他节点,也不需要做回溯,查找的路径已经规划好了。

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

 98.验证二叉搜索树

之前没做过,只判断了左右元素跟根节点的大小比较。但是除了这个比较之外,他其实还要跟根节点的父节点比较。

看了题解之后发现二叉排序树其实就是按照中序遍历有序,所以只需要按照中序遍历,然后比较前后元素大小就好了。

递归法:

class Solution {
public:
    TreeNode* pre=NULL;
    bool isValid(TreeNode* node){
        if(node==NULL) return true;

        bool left=isValid(node->left);

        if(pre!=NULL&&pre->val>=node->val) return false;
        pre=node;

        bool right=isValid(node->right);
        return left&&right;
    }
    bool isValidBST(TreeNode* root) {
        return isValid(root);
    }
};

迭代法:

我使用统一迭代法写的,卡在pre怎么写好长时间,最后发现应该写在一开始的if语句中,提出NULL的时候才证明这个节点被拿出来了。

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> st;
        if(root==NULL) return true;
        st.push(root);
        TreeNode* pre=NULL;
        while(!st.empty()){
            TreeNode* node=st.top();
            st.pop();
            if(node==NULL){
                node=st.top();
                st.pop();
                if(pre!=NULL&&pre->val>=node->val){
                    return false;
                }
                pre=node;
                cout<<node->val<<endl;
            }
            else{
                if(node->right)st.push(node->right);
                st.push(node);
                st.push(NULL);
                if(node->left) st.push(node->left); 
            }
        }
        return true;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值