question.给你二叉树的根节点root和一个表示目标和的整数targetNum。判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和targetSum。如果存在,返回true;否则,返回false。
how.怎么解决这个问题
附上代码和注释~
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {boolean}
*/
// 递归
var hasPathSum = function(root, targetSum) {
// 如果根节点为空,或者遍历到叶子结点时也没有找到符合条件的路径,返回false
if (!root) {
return false;
}
// 如果当前节点为叶子节点,且叶子节点的值等于当前目标值,证明在该树上存在符合条件的路径,返回true
if (!root.left && !root.right && root.val === targetSum) {
return true;
}
// 如果当前节点不是叶子节点,将目标值减去当前节点的值,并递归当前节点的左子节点和右子节点,有任意一个子节点返回true,则证明该树上存在符合条件的路径
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
};
// 非递归(迭代)
var hasPathSum = function(root, targetSum) {
// 如果根节点为空,则返回false
if (!root) {
return false;
}
// 维护一个栈,初始化入栈根节点
const stack = [root];
// 执行循环,循环条件为栈不为空
while (stack.length) {
// 每次循环出栈一个节点作为当前节点
let cur = stack.pop();
// 如果当前节点为叶子结点,并且当前节点的值等于目标和,则该树上存在符合条件的路径,返回true
if (!cur.left && !cur.right && cur.val === targetSum) {
return true;
}
// 如果当前节点的右子节点存在,则将右子节点的值加上当前节点的值,并将右子节点入栈
if (cur.right) {
cur.right.val = cur.right.val + cur.val;
stack.push(cur.right);
}
// 如果当前节点的左子节点存在,则将左子节点的值加上当前节点的值,并将左子节点入栈
if (cur.left) {
cur.left.val = cur.left.val + cur.val;
stack.push(cur.left);
}
}
// 如果循环结束后,没有找到符合条件的路径,则该树上不存在符合条件的路径,返回false
return false;
}