题目链接:437. Path Sum III
题目描述
You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
简而言之,任意一个结点到其任意一个子结点的路径和为SUM,有多少个
Example:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
解题思路
任意一个结点都可以当根节点,然后向下进行遍历,找寻是否存在路径和为SUM的结点。
而且条件仅限 路径和==sum,并不一定非得到叶子结点。
在参考优秀答案的时候,看到了一位老哥对递归的诠释:特此分享Leetcode
Leetcode讨论区,用户ID:fudonglai
写递归的技巧是:明白一个函数的作用并相信它能完成这个任务,千万不要跳进这个函数里面企图探究更多细节,否则就会陷入无穷的细节无法自拔。你就算浑身是铁,能压几个栈?
按照前面说的技巧,先来定义清楚每个递归函数应该做的事:
pathSum 函数:给他一个节点和一个目标值,他返回以这个节点为根的树中,和为目标值的路径总数。
count 函数:给他一个节点和一个目标值,他返回以这个节点为根的树中,能凑出几个以该节点为路径开头,和为目标值的路径总数
pathSum 和 count的区别是,count只计算以该结点为开始结点的总数目。
而pathSum,是计算以该节点为根,那么包含了该根节点下 各个结点的count。
/* 有了以上铺垫,详细注释一下代码 */
int pathSum(TreeNode root, int sum) {
if (root == null) return 0;
int pathImLeading = count(root, sum); // 自己为开头的路径数
int leftPathSum = pathSum(root.left, sum); // 左边路径总数(相信他能算出来)
int rightPathSum = pathSum(root.right, sum); // 右边路径总数(相信他能算出来)
return leftPathSum + rightPathSum + pathImLeading;
}
int count(TreeNode node, int sum) {
if (node == null) return 0;
// 我自己能不能独当一面,作为一条单独的路径呢?
int isMe = (node.val == sum) ? 1 : 0;
// 左边的小老弟,你那边能凑几个 sum - node.val 呀?
int leftBrother = count(node.left, sum - node.val);
// 右边的小老弟,你那边能凑几个 sum - node.val 呀?
int rightBrother = count(node.right, sum - node.val);
return isMe + leftBrother + rightBrother; // 我这能凑这么多个