33 - 路径总和
题目
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例: 给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
解答
递归
作者:LeetCode
链接:https://leetcode-cn.com/problems/two-sum/solution/lu-jing-zong-he-by-leetcode/
var hasPathSum = function (root, sum) {
if (!root) {
return false
}
sum -= root.val
if (!root.left && !root.right) {
return sum === 0
}
return hasPathSum(root.left, sum) || hasPathSum(root.right, sum)
};
执行用时 :100 ms, 在所有 JavaScript 提交中击败了66.08%的用户
内存消耗 :37.7 MB, 在所有 JavaScript 提交中击败了5.17%的用户
<<<<<<< HEAD:33 - 路径总和.md
迭代
原本的写法是这样的:
var hasPathSum = function (root, sum) {
if (!root) {
return false
}
let stack = [root]
while (stack.length > 0) {
let cur = stack.pop()
sum -= cur.val
if (!cur.left && !cur.right) {
if (sum === 0) {
return true
} else {
sum += cur.val // 如果不是0,那么就把减过的值放回去
}
}
if (cur.right) {
stack.push(cur.right)
}
if (cur.left) {
stack.push(cur.left)
}
}
return false;
};
但是会遇到一个反例:[1, -2, -3, 1, 3, -2, null, -1]

即当某个二叉树不平衡的时候,如这里的左边有三个叶子,而且三个叶子也都不是答案。那么其实需要加回去两次,但这个代码只能加回去一次。
作者:382615666
链接:https://leetcode-cn.com/problems/two-sum/solution/jsxie-fa-by-382615666-3/
这个作者的方法,是抛弃不修改二叉树的值这个先验的想法,而每次迭代的时候,都把现有的val
加到后面的叶子节点之中,以此与目标的sum
相比较。因此就避免了上述的情况。
var hasPathSum = function (root, sum) {
if (!root) {
return false
}
let stack = [root]
while (stack.length) {
let cur = stack.pop()
if (!cur.left && !cur.right && cur.val === sum) {
return true
}
if (cur.left) {
cur.left.val += cur.val // 直接加入到子节点之上
stack.push(cur.left)
}
if (cur.right) {
cur.right.val += cur.val
stack.push(cur.right)
}
}
return false
};
Runtime: 52 ms, faster than 98.96% of JavaScript online submissions for Path Sum.
Memory Usage: 37.1 MB, less than 69.05% of JavaScript online submissions for Path Sum.
Last updated
Was this helpful?