代码随想录 | Day21 | 二叉树:找树左下角的值&&路径总和

代码随想录 | Day21 | 二叉树:找树左下角的值&&路径总和

主要学习内容:

1.利用二叉树的谦虚遍历进行题目解答

2.to_string函数的使用

513.找树左下角的值

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

解法一:回溯

思路:

难突破的点是我们怎么知道我们找的叶子结点是最左边的

其实只需要一直往下遍历,每一层最先遍历到的肯定是左边的

那如何知道是最下面的呢?

深度最深才能是最下面的

所以我们的目标就是找深度最深的叶子结点,保存第一个遍历到的深度最深的结点。这就是我们的答案

1.函数参数和返回值

int res;
int curdepth=0;
void tra(TreeNode *t,int depth)

res记录结果

curdepth用于更新当前的最大深度

depth为当前结点的深度

2.终止条件

if(t->left==nullptr&&t->right==nullptr)
{
	if(depth>curdepth)
	{
		res=t->val;
		curdepth=depth;
	}
                
	return;
}

遍历到叶子结点并且当前叶子结点深度最深,就是我们要的答案,保存后再更新一下当前最大深度,用于找更下层的结点

3.本层代码逻辑

if(t->left)
	tra(t->left,depth+1);
if(t->right)
	tra(t->right,depth+1);

在上面更新完结果后,继续遍历左右子树,+1是每层遍历深度+1

//不省略回溯的版本
if(t->left)
{
    depth++;
    tra(t->left,depth);
    depth--;
}
if(t->right)
{
    depth++;
    tra(t->right,depth);
    depth--;
}

4.完整代码

class Solution {
public:
    vector<string> res;
    void tra(string s,TreeNode *t)
    {
        if(t==nullptr)
            return;
        if(t->left==nullptr&&t->right==nullptr)
        {
            s+=to_string(t->val);
            res.push_back(s);
            return;
        }
        s+=to_string(t->val);
        s+="->";
        tra(s,t->left);
        tra(s,t->right);
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        string s;
        tra(s,root);
        return res;
    }
};

解法二:层序遍历

我们每层第一个元素就是最左边的元素,每次都更新一下,到最后一层也会更新

只需要在模板的基础上再把每层第一个元素更新一下就行(不清楚模板可以翻看前面的层序遍历相关)

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode *> q;
        q.push(root);
        int res;
        while(!q.empty())
        {
            int size=q.size();
            res=q.front()->val;//更新
            for(int i=0;i<size;i++)
            {
                TreeNode *t=q.front();
                q.pop();
                if(t->left)
                    q.push(t->left);
                if(t->right)
                    q.push(t->right);
            }
        }
        return res;
    }

};

112.路径总和

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

解法:回溯

一个经典的树的路径问题,可以刷完回溯算法后再回来看

1.函数参数和返回值

bool flag=false;
void tra(TreeNode *t,int target)

flag是标记是否成功,找到就为ture

target是用来减的,减到0就说明找到了答案,利用一个反向思维吧算是

2.终止条件

if(t->left==nullptr&&t->right==nullptr)
{
	if(target==0)
	flag=true;
}

是叶子结点且已经减到了0,那么就是答案,标记为true

3.本层代码逻辑

易错

减去的是t的子树的val而不是t本身的val

调用的时候就要减去,这样方便终止条件进行比较,不然进入本层调用函数以后还要现场加或者减容易搞混

if(t->left)
	tra(t->left,target-t->left->val);
if(t->right)
	tra(t->right,target-t->right->val);

完整代码:

class Solution {
public:
    bool flag=false;
    void tra(TreeNode *t,int target)
    {
        if(t->left==nullptr&&t->right==nullptr)
        {
            if(target==0)
                flag=true;
        }
        if(t->left)
            tra(t->left,target-t->left->val);
        if(t->right)
            tra(t->right,target-t->right->val);
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==nullptr)
            return false;
        tra(root,targetSum-root->val);
        return flag;
    }
};
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值