代码随想录训练营day20

第六章 二叉树 part06

1.LeetCode.最大二叉树

1.1题目链接:654.最大二叉树

文章讲解:代码随想录
视频讲解:B站卡哥视频

1.2思路:采用划分数组区间的方式进行构建最大二叉树,每次先找到数组区间的最大值作为根节点

1.3附加代码如下所示:

//法1
class Solution {
public:
    TreeNode*constru(vector <int>&nums)
    {
        if(nums.size()==1)return new TreeNode(nums[0]);

        int index=0;
        int maxvalue=0;
        for(int i=0;i<nums.size();i++)//中
        {
            if(nums[i]>maxvalue)
            {
                maxvalue=nums[i];
                index=i;
            }
        }
        TreeNode*node=new TreeNode(maxvalue);
        if(index>0)//左
        {
            vector<int>leftvec(nums.begin(),nums.begin()+index);
            node->left=constru(leftvec);
        }
        if(index<nums.size()-1)//右
        {
            vector<int>rightvec(nums.begin()+index+1,nums.end());
            node->right=constru(rightvec);
        }
        return node;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return constru(nums);


    }
};

//法2
class Solution {
public:
    TreeNode*constru(vector <int>&nums,int left,int right)
    {
        if(left>=right)return nullptr;

        int index=left;
        int maxvalue=0;
        for(int i=left;i<right;i++)//中
        {
            if(nums[i]>maxvalue)
            {
                maxvalue=nums[i];
                index=i;
            }
        }
        TreeNode*node=new TreeNode(maxvalue);
       
        node->left=constru(nums,left,index);

        node->right=constru(nums,index+1,right);

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


    }
};

2.LeetCode. 合并二叉树

2.1题目链接:617.合并二叉树

文章讲解:[代码随想录](https://programmercarl.com/0617.%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91.html)
视频讲解:B站卡哥视频

2.2思路:因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。

2.3附加代码如下所示:

//迭代法
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        queue<TreeNode*>que1;
        queue<TreeNode*>que2;
       
        if(root1==NULL&&root2!=NULL)return root2;
        if(root1!=NULL&&root2==NULL)return root1;
        if(root1==NULL&&root2==NULL)return NULL;
        else 
        {
            que1.push(root1);
            que2.push(root2);
        }
        while(!que1.empty())
        {
            TreeNode* node1 = que1.front(); que1.pop();
            TreeNode* node2 = que2.front(); que2.pop();
            node1->val+=node2->val;

             // 如果两棵树左节点都不为空,加入队列
            if(node1->left!=NULL&&node2->left!=NULL)
            {
                que1.push(node1->left);
                que2.push(node2->left);
            }
             // 如果两棵树右节点都不为空,加入队列
            if(node1->right!=NULL&&node2->right!=NULL)
            {
                que1.push(node1->right);
                que2.push(node2->right);
            }
             // 当t1的左节点 为空 t2左节点不为空,就赋值过去
            if(node1->left==NULL&&node2->left!=NULL)
            {
                node1->left=node2->left;
            }
             // 当t1的右节点 为空 t2右节点不为空,就赋值过去
            if(node1->right==NULL&&node2->right!=NULL)
            {
                node1->right=node2->right;
            }
        
           
        }
         return root1;


    }
};

//上述代码简化版 迭代法
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        queue<TreeNode*>que;
        if(root1==NULL)return root2;
        if(root2==NULL)return root1;
        else 
        {
            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->right!=NULL&&node2->right!=NULL)
            {
                que.push(node1->right);
                que.push(node2->right);
            }
             // 当t1的左节点 为空 t2左节点不为空,就赋值过去
            if(node1->left==NULL&&node2->left!=NULL)
            {
                node1->left=node2->left;
            }
             // 当t1的右节点 为空 t2右节点不为空,就赋值过去
            if(node1->right==NULL&&node2->right!=NULL)
            {
                node1->right=node2->right;
            }
        
           
        }
         return root1;


    }
};
//递归法 前序遍历
class Solution {
public:
    
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        //终止条件
        if(root1==NULL)return root2;
        if(root2==NULL)return root1;

        root1->val+=root2->val;//中

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

        return root1;

    }
};

3.LeetCode.二叉搜索树中的搜索

3.1题目链接:700.二叉搜索树中的搜索

文章讲解:代码随想录
视频讲解:B站卡哥视频

3.2思路:二叉搜索树是一个有序树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。本题,其实就是在二叉搜索树中搜索一个节点。

3.3附加代码如下所示:

//迭代法 为利用到二叉搜索树
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        queue<TreeNode*>que;
        
        if(root!=NULL)que.push(root);
        else return NULL;
        while(!que.empty())
        {
            int size=que.size();
            for(int i=0;i<size;i++)
            {
                TreeNode*node=que.front();que.pop();
                if(node->val==val)
                {
                    return node;
                    
                }
                else
                {
                    if(node->left)que.push(node->left);
                    if(node->right)que.push(node->right);
                }
            }
        }
        return NULL;

    }
};

//利用二叉搜索树 迭代法
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;

    }
};
//递归法 前序遍历
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if(root==NULL)return NULL;
        
        if(root->val==val)return root;
        
        if(root->val>val)
        {
            return searchBST(root->left,val);
        }
        else if(root->val<val)
        {
            return searchBST(root->right,val);
        }
        return NULL;

    }
};

4.LeetCode.验证二叉搜索树

4.1题目链接:98.验证二叉搜索树

文章讲解:代码随想录
视频讲解:B站卡哥视频

4.2思路:不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了,我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。所以以上代码的判断逻

4.3附加代码如下所示:

//递归法  将二叉搜索树转化为有序数组检验该数组是否是有序的
class Solution {
public:
    vector<int>result;
    void traversal(TreeNode*node)
    {
        if(node==NULL)return;
        traversal(node->left);//左
        // 将二叉搜索树转换为有序数组
        result.push_back(node->val);//中
        traversal(node->right);//右
    }
    bool isValidBST(TreeNode* root) {
       result.clear();//清楚之前遍历过的结果
       traversal(root);
       for(int i=0;i<result.size()-1;i++)//注意数组越界的问题
       {
            if(result[i+1]<=result[i])return false;// 注意要小于等于,搜索树里不能有相同元素
       }
       return true;
    }
};

//常规递归法
class Solution {
public:
    long long maxval=LONG_MIN;
    bool isValidBST(TreeNode* root) {
        if(root==NULL)return true;
        bool left=isValidBST(root->left);//左

        if(maxval<root->val)maxval=root->val;//中
        else return false;

        bool right=isValidBST(root->right);//右

        return left&&right;

    }
};
//上述代码稍微处理后的 建议避免初始化最小值,如下方法取到最左面节点的数值来比较。
class Solution {
public:
    TreeNode* pre = NULL; // 用来记录前一个节点
    bool isValidBST(TreeNode* root) {
        if (root == NULL) return true;
        bool left = isValidBST(root->left);

        if (pre != NULL && pre->val >= root->val) return false;
        pre = root; // 记录前一个节点

        bool right = isValidBST(root->right);
        return left && right;
    }
};
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码随想录算法训练是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值