题目
给定一个二叉树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
/**
* 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
/**
* 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;
}
};