大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。
题目
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
思路
- 二叉树找路径,找节点啥的,看到这种题目一般大概率都是递归问题;
- 递归问题那么我们需要找递归的条件,首先我们需要一个当前的节点
node, 其次,我们要把目标值传递下去,作为判断的条件,然后还需要一个cur记录上一轮的值。这样子每一轮我们只需要判断上一轮的值cur加上当前节点node.val是否等于我们要的targetSum即可; - 如果找到了,直接返回找到了即可,如果找不到,则需要再递归去当前节点的左右子节点中找,这时候递归的转换公式我们也找出来了,
targetSum始终不变,node变成node.left或者node.right;cur变成cur+node.val; - 左右子节点中,只需要有一个符合条件即可,所以我们的判断是
左节点符合条件 || 右节点符合条件; - 然后说一下这道题目的边界,首先如果当前节点为
null,那么不用进行判断直接返回, 如果当前节点的值加上上一轮的值等于targetSum,那么我们需要判断当前节点是否为叶子节点,是的话才满足条件。那么如何判断是否叶子节点呢? 很简单,如果一个节点即没有左节点又没有右节点,那么它就是叶子节点了。
实现
/**
* 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) {
return judgeNodeSum(root, targetSum);
};
function judgeNodeSum(node, targetSum, cur = 0) {
// 空节点就不用往下找了
if (!node) {
return false;
}
// 叶子节点说明没有左右节点
if (!node.left && !node.right && node.val + cur === targetSum) {
return true;
}
// 不是当前节点,那就从当前节点的左右节点开始找
return judgeNodeSum(node.left, targetSum, cur + node.val) ||
judgeNodeSum(node.right, targetSum, cur + node.val)
}
结果
看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。