package class07;
/**
* leetcode112. 路径总和
* <p>
* 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。
* 判断该树中是否存在这样的 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。
* 如果存在,返回 true ;否则,返回 false 。
* 叶子节点 是指没有子节点的节点。
*/
//测试链接:https://leetcode.com/problems/path-sum
public class Code03_PathSum {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
//定义一个全局变量isSum,该二叉树是否存在这样一条路径,从根节点到右子节点的累加和,等于目标累加和sum。
//初始值给false。
public static boolean isSum = false;
/**
* @param root 根节点
* @param sum 目标和
* @return 当前这个树是否存在这样一条路径(从根节点到右子节点的累加和等于目标和sum)。
*/
public static boolean hasPathSum(TreeNode root, int sum) {
if (root == null) {//如果根节点就是空,则返回不存在。
return false;
}
//全局变量isSum的初始值已经设置成false了,为什么这里又设置一次?
//因为对于多个测试用例,hasPathSum()函数会执行多次。
//如果不写isSum = false,当有一次isSum变量return的是true时,那么当下次实际应该返回false时,isSum的true则干扰了结果。导致结果不对。
//所以这句需要写上。
isSum = false;
process(root, 0, sum);//执行process()函数
//当process()函数执行完毕后,如果有isSum=true的时刻,整体的返回值就是true。否则整体的返回值就是false。
return isSum;
}
/**
* @param x 当前节点
* @param preSum 当前节点(不包含当前节点)之前所有节点的累加和
* @param sum 目标累加和
*/
//为什么是void,没有返回值?
//因为process()函数的作用并不是返回什么具体的值。而是在找到这个树确实存在这样一条路径时,将isSum修改成true,这一句才是process()函数的作用。
public static void process(TreeNode x, int preSum, int sum) {
//如果x的组织树为空,并且x的右子树也为空,那么说明x是叶子节点。
if (x.left == null && x.right == null) {
//那么对于叶子节点的情况,如果从根节点到叶子节点的累加和(x.val + preSum),等于目标和。就将isSum修改成true。
if (x.val + preSum == sum) {
isSum = true;
}
}
//如果x不是叶子节点,之前所有节点的累加和preSum,就要累加上x本身的值x.val。
preSum += x.val;
//如果x的左子树不为空,就一直递归下去。去找isSum=true的时刻。如果没有,isSum则维持false。
if (x.left != null) {
process(x.left, preSum, sum);
}
//如果x的右子树不为空,就一直递归下去。去找isSum=true的时刻。如果没有,isSum则维持false。
if (x.right != null) {
process(x.right, preSum, sum);
}
}
}