Leetcode-112:路径总和

这是一篇关于LeetCode第112题的解决方案,主要探讨如何使用深度优先搜索和广度优先搜索在二叉树中寻找路径总和等于给定目标值的路径。文章详细解释了深度优先搜索时如何通过递归回溯处理节点路径和,并提供了相应的代码实现。同时,也提及了广度优先搜索的方法,即通过维护一个路径和队列与树节点队列同步更新来找到符合条件的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

这道题和题257. 二叉树的所有路径十分类似,代码也相似。

深度优先(O(N),O(N))

在本题使用深度优先的话可以使用前序递归来模拟实现,但是在递归中需要处理的是每个节点的路径和的计算要确保不对其它的节点路径和计算造成影响,所以使用递归的话在其回溯过程会需要处理那些多余的叶节点。
image.png

如在上述的路径和计算中,第一条叶子节点的路径和计算为1+2+4,如果此时不满足要求,则需要进行回溯,所以要更新已有结果为1+2,使用递归的话可以完美的解决这种问题,如下面代码中的return就可以实现有效的回溯。

if(root->left == nullptr && root->right == nullptr){
            if(num == target)   falg = true;
            // 否则继续递归
            return;
        }

具体解题代码如下:

class Solution {
public:
    void findPath(TreeNode* root,int num,int target,bool &falg){
        // 新加入了节点更新路径和
        num += root->val;
        // 到达叶子节点
        if(root->left == nullptr && root->right == nullptr){
            // 满足求解条件,结果标志为真
            if(num == target){
                falg = true;
            }   
            // 否则继续递归
            return;
        }
        // 左子树递归
        if(root->left)  findPath(root->left,num,target,falg);
        // 右子树递归
        if(root->right) findPath(root->right,num,target,falg);
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        // 根节点为空,返回false
        if(root == nullptr) return false;
        // falg用来标记求解结果
        bool falg = false;
        findPath(root,0,targetSum,falg);
        return falg;
    }
};

广度优先(O(N),O(N))

使用广度优先的话就是模拟一次层序遍历。不过相比于普通的打印路径之类的求解,此时我们需要维护一个各个节点已有的路径和队列。如下图所示。我们的路径和队列是和树节点队列一一位置对应的,也就是说,与树节点队列相同位置的路径和队列的值就是到该树节点的路径和。
image.png

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        // 空树直接返回false
        if(root == nullptr) return false;
        // 初始化广度遍历的树节点队列
        queue<TreeNode*> que;
        queue<int> num;
        que.push(root);
        num.push(root->val);
        // 队列不为空则节点未处理完
        while(!que.empty()){
            // 取出树节点队列以及路径和队列的首元素
            TreeNode* node = que.front();
            int res=num.front();
            que.pop();
            num.pop();
            // 如果到了叶子节点而且路径和满足要求则直接跳出遍历,返回true
            if(node->left==nullptr && node->right==nullptr && res==targetSum)
                return true;
            if(node->left){
                que.push(node->left);
                // 下一层节点入队,并将其对应的节点路径和存储
                num.push(node->left->val + res);
            }  
            if(node->right){
                que.push(node->right);
                // 下一层节点入队,并将其对应的节点路径和存储
                num.push(node->right->val + res);
            }  
        }
        // 节点处理完仍然没有找到加和为targetSum的路径,返回false
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值