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

题目


给定一个二叉树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;
    }
};
相关推荐
啥都鼓捣的小yao几秒前
课程11. 计算机视觉、自编码器和生成对抗网络 (GAN)
人工智能·python·深度学习·神经网络·算法·生成对抗网络·计算机视觉
ROCKY_8174 分钟前
数据结构(九)——排序
数据结构·算法·排序算法
软件派1 小时前
基于YOLO算法的目标检测系统实现指南
算法·yolo·目标检测
代码小将3 小时前
Leetcode209做题笔记
java·笔记·算法
Musennn4 小时前
leetcode 15.三数之和 思路分析
算法·leetcode·职场和发展
CM莫问7 小时前
<论文>(微软)避免推荐域外物品:基于LLM的受限生成式推荐
人工智能·算法·大模型·推荐算法·受限生成
康谋自动驾驶8 小时前
康谋分享 | 自动驾驶仿真进入“标准时代”:aiSim全面对接ASAM OpenX
人工智能·科技·算法·机器学习·自动驾驶·汽车
C++ 老炮儿的技术栈8 小时前
什么是函数重载?为什么 C 不支持函数重载,而 C++能支持函数重载?
c语言·开发语言·c++·qt·算法
yychen_java9 小时前
R-tree详解
java·算法·r-tree
MarkHard1239 小时前
Leetcode (力扣)做题记录 hot100(62,64,287,108)
算法·leetcode·职场和发展