【力扣-二叉树】11、路径总和(112)

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

112. 路径总和

题目描述

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。

叶子节点 是指没有子节点的节点。

示例 1:

输入: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出: true
复制代码

示例 2:

输入: root = [1,2,3], targetSum = 5
输出: false
复制代码

示例 3:

输入: root = [1,2], targetSum = 0
输出: false
复制代码

解析

  • 递归法(前序遍历)
    • 1、确定递归函数的参数与返回值
      • 参数:二叉树的根节点,计数器(用来判断路径和)
      • 返回值:本题不需要遍历整个树,只要找到一条符合条件的路径即可返回,所以需要添加返回值,返回值类型为bool类型
    • 2、确定终止条件
      • 遇到叶子节点,并且计数器的值为0,返回 true
      • 遇到叶子节点,但是计数器的值不为0,返回 false
    • 3、单词循环的逻辑
      • 终止的条件是判断叶子节点,在递归的过程中不考虑空节点
      • 递归函数返回值为 true,则表示找到了符合条件的路径,直接返回 true
  • 迭代法(前序遍历)
    • 使用 stack来存储节点信息
      • 该节点的指针
      • 根节点到达该节点的路径和
    • 判断终止条件与递归法相同
      • 该节点为叶子节点
      • 且根节点到达该节点的路径和等于targetSum
      • 将该节点的右孩子信息入栈
      • 将该节点的左孩子信息入栈

递归法

class Solution
{
public:
    bool hasPathSum(TreeNode *root, int targetSum)
    {
        if (root == NULL)
        {
            return false;
        }

        return traversal(root, targetSum);
    }
    

private:
    bool traversal(TreeNode *cur, int rest)
    {
        // 遇到叶子节点,剩余为0,找到了符合条件的路径,返回true
        if (!cur->left && !cur->right && rest == 0)
        {
            return true;
        }
        // 遇到了叶子节点,但是剩余的差值不为0,直接返回false
        if (!cur->left && !cur->right)
        {
            return false;
        }

        // 左
        if (cur->left)
        {
            rest -= cur->left->val;
            // 递归处理节点
            if (traversal(cur->left, rest))
            {
                return true;
            }
            rest += cur->left->val; // 回溯,撤销处理的结果
        }

        // 右
        if (cur->right)
        {
            rest -= cur->right->val;
            if (traversal(cur->right, rest))
            {
                return true;
            }
            // 回溯,撤销处理的结果
            rest += cur->right->val;
        }

        return false;
    }
};
复制代码

迭代法

class Solution
{
public:
    bool hasPathSum(TreeNode *root, int targetSum)
    {
        if (root == NULL)
        {
            return false;
        }
        // 栈中存放节点的信息对(节点指针,根节点到该节点的路径和)
        stack<pair<TreeNode *, int>> st;
        st.push(make_pair(root, root->val));

        while (!st.empty())
        {
            int size = st.size();

            for (int i = 0; i < size; i++)
            {
                // 中
                pair<TreeNode *, int> node = st.top();
                st.pop();
                // 判断是否遇到叶子节点,同时到达该叶子节点的路径和是否等于targetSum
                if (!node.first->left && !node.first->right && node.second == targetSum)
                {
                    return true;
                }
                // 右
                if (node.first->right)
                {
                    // 将该节点的右孩子的信息入栈
                    st.push(make_pair(node.first->right, node.second + node.first->right->val));
                }

                // 左
                if (node.first->left)
                {   // 将该节点的左孩子信息入栈
                    st.push(make_pair(node.first->left, node.second + node.first->left->val));
                }
            }
        }
        return false;
    }
};
复制代码

猜你喜欢

转载自juejin.im/post/7031714454018621477