「这是我参与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
- 遇到叶子节点,并且计数器的值为0,返回
- 3、单词循环的逻辑
- 终止的条件是判断叶子节点,在递归的过程中不考虑空节点
- 递归函数返回值为
true
,则表示找到了符合条件的路径,直接返回true
- 1、确定递归函数的参数与返回值
- 迭代法(前序遍历)
- 使用
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;
}
};
复制代码