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

题目


给定一个二叉树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;
    }
};
相关推荐
吴可可1238 分钟前
C#合并首尾相连多段线实战
算法·c#
KMDxiaozuanfeng44 分钟前
卡梅德生物技术快报|SPR 技术应用|基于 SPR 亲和力的中药活性成分筛选系统实现与数据分析
科技·算法·面试·考试
꧁细听勿语情꧂1 小时前
数据结构概念和算法、时间复杂度、空间复杂度引入
c语言·开发语言·数据结构·算法
Felven1 小时前
B. The 67th 6-7 Integer Problem
数据结构·算法
玉树临风ives1 小时前
atcoder ABC 454 题解
算法·深度优先·图论
钮钴禄·爱因斯晨2 小时前
聚焦操作系统中的PV操作
数据库·算法·系统架构·c#
云泽8082 小时前
笔试算法 - 双指针篇(一):移动零、复写零、快乐数与盛水容器
c++·算法
不才小强2 小时前
目标跟踪算法DeepSort实战
人工智能·算法·目标跟踪
papership2 小时前
【入门级-数学与其他:1.数及其运算:进制与进制转换:二进制、八进制、十进制、十六进制】
算法
ComputerInBook2 小时前
数字图像处理(4版)——第 4 章——频域滤波(下)(Rafael C.Gonzalez&Richard E. Woods)
人工智能·算法·计算机视觉·频域滤波