给你二叉树的根节点
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
java 解题思路及代码实现
package com.java.leetcode.tree;
import com.java.leetcode.compent.TreeNode;
/**
* 给你二叉树的根节点 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
*/
public class hasPathSum112 {
/**
* 该题目只判断 不统计所有路径详情
* 因此 遇到返回即可
* 因此有以下思路:
* 遍历树节点,遇到叶子结点停止,为一个完整路径, 路径值减去count 值是否为0 来作为路径是存在的依据
* 递归:
* 1、确定入参和返回值类型
* 入参: node, count(每一次减去当层节点)
* return :true/false
* 2、确定终止条件:
* 遇到叶子结点终止 (不到下一层空节点)
* 3、确定单层逻辑:
* 前序遍历为例:
* 遍历节点,count-val
* 判断是否为叶子结点,并且count==0 是返回true/false
* 不是继续遍历左/右子节点
* 回溯 count值进入下一层
* 因此有如下代码:
* @param root
* @param targetSum
* @return
*/
public boolean hasPathSum(TreeNode root, int targetSum) {
// 终止条件
if(root==null){
return false;
}
return traversal(root,targetSum-root.val);
}
public boolean traversal(TreeNode root, int num) {
// 叶子结点且路径成立
if(root.left==null&&root.right==null&&num==0){
return true;
}
//否则 叶子结点路径不成立 返回false;
if(root.left==null&&root.right==null){
return false;
}
//非叶子结点
if(root.left!=null){
num=num-root.left.val;
if(traversal(root.left,num)) return true;
num=num+root.left.val;
}
if(root.right!=null){
num=num-root.right.val;
// 回溯
if(traversal(root.right,num)) return true;
//回溯,撤销处理结果
num=num+root.right.val;
}
return false;
}
}