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

今天是学习二叉树的第四天。主要的学习内容有:通过递归查找二叉树最底层最左节点的值;通过回溯遍历二叉树的每条路径并求和;通过中序遍历和前序遍历,中序遍历和后序遍历构建唯一的二叉树。

513.找树左下角的值

题目链接:513. 找树左下角的值 - 力扣(LeetCode)

刚拿到这个题目的第一想法,是采用层次遍历。层次遍历完后直接输出最底层数组的第一个值,对应的就是二叉树最底层的最左节点。代码实现如下:
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        vector<vector<int>> result;
        TreeNode* cur=root;
        int size=0;
        int depth=0;
        que.push(root);
        while(!que.empty())
        {
            vector<int> vec;  
            size=que.size();
             depth++;
            while(size--)
            {
                cur=que.front();
                que.pop();
                if(cur!=NULL) vec.push_back(cur->val);
                if(cur->left!=NULL) que.push(cur->left);
                if(cur->right!=NULL) que.push(cur->right);
            }
            result.push_back(vec);
        }
        return result[depth-1][0];
    }
};

接着开始琢磨怎么用递归进行解决。自己没有实现出来。通过观看随想录的视频讲解有了思路。进行递归时需要记录深度,当深度得到更新时就更新最大值。由于不管是哪一种遍历方式,遍历的顺序一定是先左后右,所以第一次更新的一定是新一层的最左节点。同时,在遍历过程中需要进行回溯。主要回溯的内容是将深度进行还原。代码实现如下:
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
int max_depth=-1;
int result=-1;
void order(TreeNode* root,int depth)
{
    if(root->left==NULL&&root->right==NULL)
    {
        if(depth>max_depth)
        {
            max_depth=depth;
            result=root->val;
        }
    }
    if(root->left!=NULL) order(root->left,depth+1);
    if(root->right!=NULL) order(root->right,depth+1);
}
    int findBottomLeftValue(TreeNode* root) {
        order(root,0);
        return result;
    }
};

112. 路径总和 

题目链接:112. 路径总和 - 力扣(LeetCode)

这个题目和昨天做的“257.二叉树所有路径”是一致的思想,也是通过递归和回溯来完整的遍历二叉树的每条路径。只需要添加的逻辑是遍历完一条完整路径后进行求和,并判断该路径是否满足要求。具体代码实现如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
bool issame=0;
    void order(TreeNode* root,vector<int> &vec,int result)
    {
        //if(root==NULL) return;
        vec.push_back(root->val);
        if(root->left==NULL&&root->right==NULL)
        {
            int temp=0;
            for(int i=0;i<vec.size();i++) temp+=vec[i];
            if(result==temp) issame=1;
            return;
        }
        if(root->left!=NULL)
        {
            order(root->left,vec,result);
            vec.pop_back();
        }
        if(root->right!=NULL)
        {
            order(root->right,vec,result);
            vec.pop_back();
        }
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        vector<int> vec;
        if(root==NULL) return false;
        else
        {
            order(root,vec,targetSum);
            return issame;
        }
        
    }
};

113. 路径总和ii

题目链接:113. 路径总和 II - 力扣(LeetCode)

这个题与112是一致的。无非是一个是求和,一个是求和后对这个路径进行记录。没什么区别。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void order(TreeNode* root,vector<int> &vec,vector<vector<int>> &result,int target)
    {
        vec.push_back(root->val);
        if(root->left==NULL&&root->right==NULL)
        {
            int temp=0;
            for(int i=0;i<vec.size();i++) temp+=vec[i];
            if(temp==target) result.push_back(vec);
        }
        if(root->left!=NULL) 
        {
            order(root->left,vec,result,target);
            vec.pop_back();
        }
        if(root->right!=NULL) 
        {
            order(root->right,vec,result,target);
            vec.pop_back();
        }

    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        vector<int> vec;
        vector<vector<int>> result;
        if(root==NULL) return result;
        else
        {
             order(root,vec,result,targetSum);
        return result;

        }
       
    }
};

106.从中序与后序遍历序列构造二叉树

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

这个题属于比较难的一道题,题目意思是根据中序遍历和后序遍历的结果,构建唯一的二叉树。题目的基本步骤总结如下:
1.如果中序序列和后序序列为0,返回空指针

2.提取后序序列的最后一个值,这个值是整个二叉树的根节点,并创建根节点root。

3.如果中序序列和后序序列只有一个值,返回该根节点root。

4.找到root节点的值在中序序列中的位置,根据该节点将中序序列分割为左子树和右子树,这一步的结果是左子树的中序序列和右子树的中序序列。

5.根据中序序列的左子树大小,将后序序列的根节点去掉,根据前一步得到的左子树中序序列得到的大小对后序序列进行切割。得到的结果是左子树的后序序列和右子树的后序序列。

6.递归处理左子树和右子树,并赋值给root->left和root->right.

7.返回root

代码具体的实现思路如下:
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
TreeNode* order(vector<int>& inorder, vector<int>& postorder)
{
    //第一步,确定数组不为空
        if(postorder.size()==0) return NULL;

        //第二步,取出根节点
        int size=postorder.size()-1;
        int rootvalue=postorder[size];
        TreeNode* root=new TreeNode(rootvalue);

        //第三步,数组大小为1返回根节点
        if(postorder.size()==1) return root;

        //第四步,对中序数组进行切割
        int index=0;
        for(index=0;index<inorder.size();index++)
        {
            if(inorder[index]==rootvalue) break;
        }
        vector<int> leftinorder(inorder.begin(),inorder.begin()+index);
        vector<int> rightinorder(inorder.begin()+index+1,inorder.end());

        //第五步,对后序数组进行切割
        postorder.resize(postorder.size()-1);
        vector<int> leftposrorder(postorder.begin(),postorder.begin()+leftinorder.size());
        vector<int> rightpostorder(postorder.begin()+leftinorder.size(),postorder.end());

        //第六步,递归处理左中序左后序,右中序右后序
        root->left=buildTree(leftinorder,leftposrorder);
        root->right=buildTree(rightinorder,rightpostorder);
        return root;
}
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size()==0||postorder.size()==0) return NULL;
        TreeNode* root=order(inorder,postorder);
        return root;
    }
};

105.从前序与中序遍历序列构造二叉树

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

这个题目与上题一致。唯一不同的是对前序数组处理时根节点在第一个,后序数组的根节点在末尾。其他的做法基本是一致的。需要注意的是,为了获取唯一的二叉树序列,只能通过前序遍历和中序遍历,后序遍历和中序遍历实现。前序遍历和后序遍历不能唯一的构建二叉树。具体代码实现如下:
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(inorder.size()==0||preorder.size()==0) return NULL;
        int rootvalue=preorder[0];
        TreeNode* root=new TreeNode(rootvalue);
        if(inorder.size()==1&&preorder.size()==1) return root;
        int index=0;
        for(index=0;index<inorder.size();index++)
        {
            if(inorder[index]==rootvalue) break;
        }
        vector<int> leftinorder(inorder.begin(),inorder.begin()+index);
        vector<int> rightinorder(inorder.begin()+index+1,inorder.end());

        vector<int> newpre(preorder.begin()+1,preorder.end());
        vector<int> leftpreorder(newpre.begin(),newpre.begin()+leftinorder.size());
        vector<int> rightpreorder(newpre.begin()+leftinorder.size(),newpre.end());
        root->left=buildTree(leftpreorder,leftinorder);
        root->right=buildTree(rightpreorder,rightinorder);
        return root;
    }
};

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第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 ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值