代码随想录算法训练营第十六天|513.找树左下角的值,112. 路径总和,106.从中序与后序遍历序列构造二叉树,105.从前序与中序遍历序列构造二叉树

513. 找树左下角的值 - 力扣(LeetCode)

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

示例 1:

输入: root = [2,1,3]
输出: 1

思路:这里找左下角的值,要满足两个条件,一是最底层,二是最左边。

解决:采用层次遍历,最后一层的第一个数就是要找的数。

代码:

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);
        int n;//每层的结果
        while(!que.empty()){
            int size=que.size();
            for(int i=0;i<size;i++){
                TreeNode* t=que.front();
                que.pop();
                if(i==0) n=t->val;//每层最左边的
                if(t->left) que.push(t->left);
                if(t->right) que.push(t->right);
            }
        }
        return n;
    }
};

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

思路:其实就是用代码模拟手动建树过程,一步一步还原手动步骤。

解决:分步骤解答:①判断数组为空;②利用后序数组最后元素分割中序数组,分为中序左数组和中序右数组;③再利用中序左数组和中序右数组分割后序数组,分为后序左数组和后序右数组;④递归步骤②。

注意:这里每次切割完中序数组后都要,舍去后序数组最后一个元素;中序分割和后序分割的区别,中序分割需要剔除后序数组最后元素,后序分割则不需要,根据中序左数组和中序右数组分割就行。

代码:

class Solution {
private:
    TreeNode* traversal (vector<int>& inorder, vector<int>& postorder){
        if(postorder.size()==0) return NULL;//第一步判空

        //第二步找到后序数组最后元素
        int rootg =postorder[postorder.size()-1];
        TreeNode* root=new TreeNode(rootg);//该节点作为父亲节点

        if(postorder.size()==1) return root;//最后遍历如果后序数组为就一个,说明是叶子节点,直接返回

        //第三步分割数组
        //先找到分割位置
        int n;
        for(n=0;n<inorder.size();n++){
            if(inorder[n]==rootg) break;//记录分割位置
        }
        //通过分割位置分割中序数组
        vector<int> leftinorder(inorder.begin(),inorder.begin()+n);//中序左数组
        vector<int> rightinorder(inorder.begin()+n+1,inorder.end());//中序右数组

        //后序数组尾部元素舍去
        postorder.resize(postorder.size()-1);

        //第四步分割后序数组
        vector<int> leftpostorder(postorder.begin(),postorder.begin()+leftinorder.size());//后序左数组
        vector<int> rightpostorder(postorder.begin()+leftinorder.size(),postorder.end());//后序右数组

        //第五步链接左右子节点
        root->left=traversal(leftinorder,leftpostorder);
        root->right=traversal(rightinorder,rightpostorder);

        return root;
    }
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {

        if (inorder.size() == 0 || postorder.size() == 0) return NULL;
        return traversal(inorder, postorder);

    }
};

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

思路:这里和上题类似,用前序和中序确定二叉树,前序是从前序数组第一个元素分割。

解决:同106

代码:

class Solution {
private:
    TreeNode* traversal (vector<int>& inorder, vector<int>& preorder){
        if(preorder.size()==0) return NULL;//第一步判空

        //第二步找到前序数组最后元素
        int rootg =preorder[0];
        TreeNode* root=new TreeNode(rootg);//该节点作为父亲节点

        if(preorder.size()==1) return root;//最后遍历如果前序数组为就一个,说明是叶子节点,直接返回

        //第三步分割数组
        //先找到分割位置
        int n;
        for(n=0;n<inorder.size();n++){
            if(inorder[n]==rootg) break;//记录分割位置
        }
        //通过分割位置分割中序数组
        vector<int> leftinorder(inorder.begin(),inorder.begin()+n);//中序左数组
        vector<int> rightinorder(inorder.begin()+n+1,inorder.end());//中序右数组

        //前序数组头部元素舍去
        preorder.erase(preorder.begin());

        //第四步分割前序数组
        vector<int> leftpreorder(preorder.begin(),preorder.begin()+leftinorder.size());//前序左数组
        vector<int> rightpreorder(preorder.begin()+leftinorder.size(),preorder.end());//前序右数组

        //第五步链接左右子节点
        root->left=traversal(leftinorder,leftpreorder);
        root->right=traversal(rightinorder,rightpreorder);

        return root;
    }
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {

        if (inorder.size() == 0 || preorder.size() == 0) return NULL;
        return traversal(inorder, preorder);

    }
};

112. 路径总和 - 力扣(LeetCode)

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

思路:从根节点开始依次搜索子节点,最后相加结果要等于总和,这里采用递归和回溯来判断是否接近于目标值。

解决:①首先,如果遇到叶子节点并且和为目标值,返回true;

                ②如果左右子节点都是叶节点但和不是目标值,返回false;

                ③判断左右子节点是否为空;

                ④先减去父节点的数再递归左右子节点;

                ⑤如果递归返回false,再加父节点数。

代码:

class Solution {
private:
    bool traversal(TreeNode* root,int cur){
        if(!root->left&&!root->right&&cur==0) return true;
        if(!root->left&&!root->right) return false;
        if(root->left){
            cur-=root->left->val;
            if(traversal(root->left,cur)) return true;
            cur+=root->left->val;//回溯父节点
        }
        if(root->right){
            cur-=root->right->val;
            if(traversal(root->right,cur)) return true;
            cur+=root->right->val;//回溯父节点
        }
        return false;
    }
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == NULL) return false;
        return traversal(root, targetSum - root->val);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值