题目:
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)
示例 1:
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8 输出:3 解释:和等于 8 的路径有 3 条,如图所示。
从题目给到“路径方向必须是向下的,只能从父节点到子节点”可以联想到这道题的解法应该与二叉树的深度遍历有关系。
这道题目的思路根据示例的图解容易想到:
一开始,我们获取到了根节点的值,也知道了要达成目标整数,此时起步的二叉树节点值之和为0,此时题目给到目标整数的值是多少,我们距离这个目标整数就差多少。
假设根节点的值比目标整数小(如果根节点值比目标整数的值大,那么子节点就需要是负数),我们遍历该节点的子节点(同时遍历左和右),并告诉子节点距离目标整数还差多少,
如果子节点的值仍然小于这个差值,就再往下走,并告诉再下一层的节点,在上两层节点的值都已经加起来后,距离目标整数还差多少...依次类推,
最后发现某个节点的值刚好等于遍历它时传进来的差值,就说明此时已经刚好达到了目标整数的值,也说明找到了一条接节点值之和等于目标整数的路径。
通过这个思路,我们在确定某一个节点为出发点时,能找到从这个点开始能找到找到多少条符合题目要求的路径。
此部分逻辑代码:
public int rootSum(TreeNode root, Long sum) {
int ret = 0;
if (root == null) {
return 0;
}
if (root.val == sum) {
ret++;
}
ret += rootSum(root.left, sum - root.val);
ret += rootSum(root.right, sum - root.val);
return ret;
}
但是我们的题目需要我们求出的一个完整二叉树每一个节点开始能找到多少符合要求的路径的总和,因此上面的rootSum方法,需要被整个二叉树的每一个节点调用。
所以,我们还要在外面实现一层递归,先让二叉树的根节点执行rootSum()方法,求得从根节点开始能找到多少条路径,然后让左右子节点执行rootSum()方法,把根节点开始的路径数左右子节点开始获得的路径数相加,向下递归直到所有的节点都执行完成rootSum()方法。
public int pathSum(TreeNode root, int targetSum) {
int ret = 0;
if (root == null) {
return 0;
}
ret = rootSum(root, (long)targetSum);
ret += pathSum(root.left, targetSum);
ret += pathSum(root.right, targetSum);
return ret;
}
完整代码:
class Solution {
public int pathSum(TreeNode root, int targetSum) {
int ret = 0;
if (root == null) {
return 0;
}
ret = rootSum(root, (long)targetSum);
ret += pathSum(root.left, targetSum);
ret += pathSum(root.right, targetSum);
return ret;
}
public int rootSum(TreeNode root, Long sum) {
int ret = 0;
if (root == null) {
return 0;
}
if (root.val == sum) {
ret++;
}
ret += rootSum(root.left, sum - root.val);
ret += rootSum(root.right, sum - root.val);
return ret;
}
}