代码随想录算法训练营43期 | Day 16—— 513. 找树左下角的值、112. 路径总和、106.从中序与后序遍历序列构造二叉树

17 篇文章 0 订阅

代码随想录算法训练营43期 | Day 16

513. 找树左下角的值

class Solution {
public:
    int maxdepth = INT_MIN;
    int result;
    //确定递归函数的返回值和参数,根节点 和 深度deepth 找到叶子结点 比较深度
    void getVal(TreeNode* node, int deepth)
    {
        //递归终止的条件
        if(node->left==nullptr&&node->right==nullptr)
        {
            if(deepth>maxdepth)
            {
                maxdepth = deepth;
                result = node->val;
            }
            return ;
        }
        //
        if(node->left)
        {
            deepth++;
            getVal(node->left,deepth);
            deepth--;
        }
        if(node->right)
        {
            deepth++;
            getVal(node->right,deepth);
            deepth--;
        }
        return ;
    }

    int findBottomLeftValue(TreeNode* root) {
        getVal(root,0);
        return result;
    }
};

层序遍历:

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        //层序遍历 返回最底层第一个节点
        //定义一个双向队列 
        queue<TreeNode*> que;
        if(root!=nullptr)
        {
             que.push(root);
        }
        //用于保存最后结果
        int result;
        while(!que.empty())
        {
            //队列中的长度
            int size = que.size();
            for(int i = 0; i<size;i++)
            {
                TreeNode* node = que.front();
                que.pop();
                //左
                if(i==0) 
                result = node->val;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
       return result;
    }
};

112. 路径总和

寻求二叉树中目标和,元素相加等于目标和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例: 给定如下二叉树,以及目标和 sum = 22,

在这里插入图片描述

解题思路

  1. 确定遍历顺序
  2. 确定递归终止条件
  3. 确定单层递归逻辑

遍历顺序:前序、中序、后序均可

//确定传入的参数和返回值,根节点、目标值,遇到节点,做减法
bool traversal(TreeNode* node,int count)
{
	//遇到叶子节点, 找到路径 返回true
	if(node->left==nullptr&&node->right==nullptr&&count==0)
	return true;
	//遇到叶子节点,同时count不为0 返回false
	if(node->left==nullptr&&node->right==nullptr&&node!=0) 		 return false; 
	//左
	if(node->left) {
		count = count - node->left->value;
		if(traversal(node->left,count)){
			return true;
			count+=node->left->val;
			}
}
	//右
	if(node->right)
	{
		count = count - node->right->value;
		if(traversal(node->right,count)) 
			return true;
			count+= node->right->value;
	}
	return false;

广度优先搜索:

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root == nullptr){
            return false;
        }
        //定义一个队列
        queue<TreeNode*> que_node;
        queue<int> que_val;
        //根节点入队
        que_node.push(root);
        que_val.push(root->val);
        //循环条件,队列不为空
        while(!que_node.empty())
        {
            TreeNode* cur = que_node.front();//获取队列中队头元素
            int temp  = que_val.front();
            //出队
            que_node.pop();
            que_val.pop();
            //判断返回条件
            if(cur->left==nullptr&&cur->right==nullptr)
            {
                if(temp==targetSum)
                {
                    return true;
                }
            }
            //左
            if(cur->left)
            {
                que_node.push(cur->left);
                que_val.push(cur->left->val + temp);
            }
            //右
            if(cur->right)
            {
                que_node.push(cur->right);
                que_val.push(cur->right->val + temp);
            }
        }
        return false;
    }
};

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

根据一棵树的中序遍历与后序遍历构造二叉树。
注意: 你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树

在这里插入图片描述

解题思路

一个中序、后序确定一个二叉树
一个前序、中序确定一个二叉树
一个前序、后序无法确定一个二叉树

根据中序、后续确定二叉树
根据后序确定根节点,根据中序确定左右子树节点

class Solution {
public:

    //确定函数参数的返回值和参数列表
    TreeNode* traversal(vector<int> inorder, vector<int> postorder)
    {
        //1. if数组为null 返回 null
        if(postorder.size()==0) return nullptr;

        //2. 后续遍历,返回后序遍历中的最后一个元素为根节点,将其构造为根节点
        int rootValue = postorder[postorder.size() - 1];
        TreeNode* root = new TreeNode(rootValue);

        //3. 返回叶子节点
        if(postorder.size()==0) return root;

        //4. z找到中序遍历的分割点, 条件就是与根节点的值相同的节点 则为分割点
        int delimiterIndex;
        for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++)
        {
            if(inorder[delimiterIndex]==rootValue)
            {
                break;
            }
        }

        // 5. 将中序数组分开,从根节点分为两部分
        vector<int> leftInorder(inorder.begin(), inorder.begin()+delimiterIndex);
        vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end() );

        //6. postorder 舍弃末尾元素 
        postorder.resize(postorder.size() - 1);

        //7. 切割后序元素,分割原则是
        //依然左闭右开,注意这里使用了 左中序 数组大小作为切割点
        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;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size()==0||postorder.size()==0)  return nullptr;
        return traversal(inorder, postorder);
    }
};
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值