题目链接:112. 路径总和
题目:
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
示例 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
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。
示例 3:
输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。
提示:
- 树中节点的数目在范围 [0, 5000] 内
- -1000 <= Node.val <= 1000
- -1000 <= targetSum <= 1000
解题思路:
方案一:递归
1、递归1:
代码(c++):
//递归 前序遍历
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
return traversal(root, 0, targetSum);
}
private:
//确定递归的参数和返回值
//参数:根节点、路径和、目标值,返回值:布尔类型
bool traversal(TreeNode* cur, int sum, const int& targetSum) {
//确定终止条件
//当前节点为空,则返回0
if (!cur) return 0;
//确定单层递归逻辑
sum += cur->val; //中
//如果遍历到叶子节点
if (!cur->left && !cur->right) {
return sum == targetSum ? true :false;
}
return traversal(cur->left, sum, targetSum) || traversal(cur->right, sum, targetSum); //递归左右子树
}
};
2、递归精简版:
//递归精简版
class Solution {
public:
//确定递归的参数和返回值
//参数:根节点、目标和
bool hasPathSum(TreeNode* root, int targetSum) {
//确定终止条件
if (!root) return false;
//确定单层递归逻辑
//如果遍历到叶子节点,经过处理的和等于叶子节点值
if (!root->left && !root->right && targetSum == root->val) return true;
//递归左右子树
return hasPathSum(root->left, targetSum - root->val) || hasPathSum(root->right, targetSum - root->val);
}
};
方案二:迭代
如果使用栈模拟递归的话,那么这里有个问题:如何做回溯呢?此时栈里的一个元素不仅要记录该节点指针,还要记录从头结点到该节点的路径数值总和。在c++里就我们用pair结构来存放这个栈里的元素。定义为:pair<节点指针,路径数值>
,即pair<treenode*, int>
。
代码(c++):
//迭代 前序遍历
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
stack<pair<TreeNode*, int>> stk; //节点 路径和
if (root) stk.push(pair<TreeNode*, int>(root, root->val));
int sum = 0; //路径和
while (!stk.empty()) {
pair<TreeNode*, int> cur = stk.top(); //取出栈顶元素
stk.pop();
//如果遍历到叶子节点并且路径和等于目标和
if (!cur.first->left && !cur.first->right && cur.second == targetSum) return true;
//如果左右孩子不为空,则压栈
if (cur.first->right) stk.push(pair<TreeNode*, int>(cur.first->right, cur.second + cur.first->right->val));
if (cur.first->left) stk.push(pair<TreeNode*, int>(cur.first->left, cur.second + cur.first->left->val));
}
return false;
}
};