每日一题——二叉树中和为某一值的路径

题目


给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。

  • 该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
  • 叶子节点是指没有子节点的节点
  • 路径只能从父节点到子节点,不能从子节点到父节点
  • 总节点数目为n

例如:

给出如下的二叉树,sum=22,

返回true,因为存在一条路径 5→4→11→2 的节点值之和为 22

数据范围:

  • 树上的节点数满足 0≤n≤10000
  • 每个节点的值都满足 ∣val∣≤1000

要求:空间复杂度 O(n),时间复杂度 O(n)

进阶:空间复杂度 O(树的高度),时间复杂度 O(n)

参数说明:二叉树类,二叉树序列化是通过按层遍历,#代表这这个节点为空节点,举个例子:

复制代码
  1
 / \
2   3
   /
  4

以上二叉树会被序列化为 {1,2,3,#,#,4}

示例1

复制代码
输入:
{5,4,8,1,11,#,9,#,#,2,7},22
返回值:
true

示例2

复制代码
输入:
{1,2},0
返回值:
false

示例3

复制代码
输入:
{1,2},3
返回值:
true

示例4

复制代码
输入:
{},0
返回值:
false

思路1


可以在根节点每次往下一层的时候,将sum减去节点值,最后检查是否完整等于0。遍历的方法可以选取二叉树常用的递归前序遍历,因为每次进入一个子节点,更新sum值以后,相当于对子树查找有没有等于新目标值的路径,因此可以递归求解。

解答代码1


cpp 复制代码
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * @param root TreeNode类 
     * @param sum int整型 
     * @return bool布尔型
     */
    bool hasPathSum(TreeNode* root, int sum) {
        // write code here
        if (root == nullptr) {
            // 此时已经递归过了叶子节点,还没找到符合的,返回false
            return false;
        }
        if (root->left == nullptr && root->right == nullptr
            && root->val == sum) {
            // 左右子树都未null,说明该节点为叶子节点,递归到此的val=sum则说明找到了这条路径
            return true;
        }
        // 更新sum值,递归左右子树
        return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
    }
};

思路2


使用栈辅助,进行dfs(深度优先搜索)遍历,检查往下的路径中是否有等于sum的路径和。

栈中记录遍历的节点和到该节点的路径和(pair)。

解答代码2


cpp 复制代码
/**
 * struct TreeNode {
 *  int val;
 *  struct TreeNode *left;
 *  struct TreeNode *right;
 *  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
#include <stack>
class Solution {
  public:
    /**
     * @param root TreeNode类
     * @param sum int整型
     * @return bool布尔型
     */
    bool hasPathSum(TreeNode* root, int sum) {
        // write code here
        if (root == nullptr) {
            return false;
        }
        // 采用dfs遍历
        stack<pair<TreeNode*, int>> stack;// 记录节点和到该节点的路径和
        stack.emplace(root, root->val);// 先将根节点入栈
        while (!stack.empty()) {
            auto now = stack.top();
            stack.pop();

            // 找到叶子结点,判断是否等于目标值
            if (now.first->left == nullptr && now.first->right == nullptr
                    && now.second == sum) {
                return true;
            }

            // 将左右节点入栈,求路径和
            if (now.first->left != nullptr) {
                stack.emplace(now.first->left, now.second + now.first->left->val);
            }
            if (now.first->right != nullptr) {
                stack.emplace(now.first->right, now.second + now.first->right->val);
            }
        }

        return false;
    }
};
相关推荐
Q741_14711 分钟前
C++ 模拟题 力扣495. 提莫攻击 题解 每日一题
c++·算法·leetcode·模拟
Felven1 小时前
A. Be Positive
算法
小O的算法实验室1 小时前
2026年COR SCI2区,自适应K-means和强化学习RL算法+有效疫苗分配问题,深度解析+性能实测,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
青岛少儿编程-王老师1 小时前
CCF编程能力等级认证GESP—C++7级—20250927
数据结构·c++·算法
夏鹏今天学习了吗2 小时前
【LeetCode热题100(39/100)】对称二叉树
算法·leetcode·职场和发展
天选之女wow3 小时前
【代码随想录算法训练营——Day34】动态规划——416.分割等和子集
算法·leetcode·动态规划
Boop_wu3 小时前
[数据结构] 哈希表
算法·哈希算法·散列表
Mingze03144 小时前
C语言四大排序算法实战
c语言·数据结构·学习·算法·排序算法
IT古董5 小时前
【第五章:计算机视觉-项目实战之生成式算法实战:扩散模型】3.生成式算法实战:扩散模型-(3)DDPM模型训练与推理
人工智能·算法·计算机视觉
独自破碎E5 小时前
Leetcode2166-设计位集
java·数据结构·算法