题目:
给你二叉树的根节点 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
解释:由于树是空的,所以不存在根节点到叶子节点的路径。
解析:
这道题使用dfs+回溯来解决:
使用深度优先搜索遍历所有可能的路径,在遍历过程中:
从根节点开始,记录当前路径的累加和
到达叶子节点时,检查路径和是否等于目标值
找到一条符合条件的路径就立即返回
如何表示路径和?
从目标值开始,每经过一个节点就减去其值,检查是否减到0
递归终止条件是什么?
到达叶子节点时,判断剩余值是否为0
如果当前节点为空,返回false
如何遍历所有路径?
对每个非叶子节点,分别探索其左子树和右子树
使用递归进行深度优先搜索
具体代码:
/** * @param {TreeNode} root * @param {number} targetSum * @return {boolean} */varhasPathSum=function(root,targetSum){// 1. 处理空树的情况:空树没有路径,直接返回falseif(!root)returnfalse// 2. 从根节点开始遍历,初始sum = targetSum - 根节点值// 因为根节点的值已经计入路径和了returntraversal(root,targetSum-root.val)};functiontraversal(node,sum){// 3. 终止条件1:到达叶子节点,且剩余sum为0// sum === 0 表示路径和正好等于targetSum// !node.left && !node.right 确保是叶子节点if(sum===0&&!node.left&&!node.right)returntrue// 4. 终止条件2:到达叶子节点,但剩余sum不为0// 说明这条路径的和不等于targetSumif(sum!==0&&!node.left&&!node.right)returnfalse// 5. 递归处理左子树if(node.left){// 5.1 做出选择:将左子节点的值从sum中减去sum-=node.left.val// 5.2 递归探索左子树if(traversal(node.left,sum)){returntrue// 如果左子树找到符合条件的路径,直接返回true}// 5.3 撤销选择(回溯):恢复sum的值// 因为要尝试右子树,需要回到之前的状态sum+=node.left.val}// 6. 递归处理右子树if(node.right){// 6.1 做出选择:将右子节点的值从sum中减去sum-=node.right.val// 6.2 递归探索右子树if(traversal(node.right,sum)){returntrue// 如果右子树找到符合条件的路径,直接返回true}// 6.3 撤销选择(回溯):恢复sum的值sum+=node.right.val}// 7. 左右子树都没有找到符合条件的路径,返回falsereturnfalse}