您的位置:首页 > 其它

leetcode[437] PathSum III 个人题解

2018-03-19 23:04 363 查看
题目描述: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.


题目大意:

给定一颗二叉树,每个节点包含一个整数值。计算所有和为给定值的路径个数。路径不一定以根开始,也不一定以叶子结束,但是必须自上而下(从双亲结点到孩子节点)树节点个数不超过1000,并且节点值的范围在-1,000,000到1,000,000之间。思路:首先,遇到二叉树问题,很自然的可以想到,要用到递归的方法,按照我个人对递归方法的理解,首先需要判断递归结束的条件。在本题中,递归结束的条件就是对应节点为空即可。代码如下:/**

* Definition for a binary tree node.

* public class TreeNode {

* int val;

* TreeNode left;

* TreeNode right;

* TreeNode(int x) { val = x; }

* }

*/

class Solution {

public int pathSum(TreeNode root, int sum) {

If(root==null)return 0;//当root为null时,代表递归的结束

//分别判断以 1.当前root为路径起始点向下查找2.以root.left为路径起始点向下查找。3.以root.right为路径起

//始点向下查找

return pathSum(root.left,sum)+pathSum(root.right,sum)+FindPath(root,sum);

}

Public static int FindPath(TreeNode root,int sum){//同样这也是一个递归操作

If(root==null)return 0;

//以root为起点,继续向下查找,知道找到了符合条件的路径,当找到后,对应的结果数增加1;

return ((root.val==sum)?1:0)+FindPath(root.left,sum-root.val)+FindPath(root.right,sum-root.val);

}

}
同时我也遇到了大神们用hashMap写的思路,我也研读了一下。


public int pathSum(TreeNode root, int sum) {
if (root == null) {
return 0;
}
Map<Integer, Integer> map = new HashMap<>();
map.put(0, 1);
return findPathSum(root, 0, sum, map);
}
private int findPathSum(TreeNode curr, int sum, int target, Map<Integer, Integer> map) {
if (curr == null) {
return 0;
}
// update the prefix sum by adding the current val
sum += curr.val;
// get the number of valid path, ended by the current node
int numPathToCurr = map.getOrDefault(sum-target, 0);
// update the map with the current sum, so the map is good to be passed to the next recursion
map.put(sum, map.getOrDefault(sum, 0) + 1);
// add the 3 parts discussed in 8. together
int res = numPathToCurr + findPathSum(curr.left, sum, target, map)
+ findPathSum(curr.right, sum, target, map);
// restore the map, as the recursion goes from the bottom to the top
map.put(sum, map.get(sum) - 1);
return res;
}
这是一个很好的想法,并花了我一些时间来弄清楚背后的逻辑。
希望我的评论可以帮助理解这个解决方案。
1前缀存储递归中从根节点到当前节点的总和
2在到达当前节点之前,地图存储<前缀和,频率>对。我们可以想象一条从根节点到当前节点的路径。从路径中间的任何节点到当前节点的总和=从根节点到当前节点的总和与中间节点的前缀总和之差。
3我们正在寻找总和达到给定目标值的连续节点,这意味着2.中讨论的差异应该等于目标值。另外,我们需要知道有多少差异等于目标值。
4这里是map。map存储当前节点路径中所有可能和的频率。如果当前总和与目标值之间的差异存在于映射中,那么必须在路径中间存在节点,使得从该节点到当前节点的总和等于目标值。
5请注意,中间可能有多个节点满足4中讨论的内容。map中的频率用于帮助解决此问题。
6因此,在每一次递归中,map都会存储我们需要计算总计达到目标的范围数的所有信息。请注意,每个范围从中间节点开始,由当前节点结束。
7要获得路径总数,我们将树中EACH节点结束的有效路径数加起来。
8每次递归都会返回以当前节点为根的子树中的有效路径总数。这笔款项可分为三部分:
- 以当前节点的左侧子节点为根的子树中的有效路径总数
- 以当前节点的右侧子节点为根的子树中的有效路径总数
- 当前节点结束的有效路径数量
这个解决方案有趣的部分是前缀从顶部(根)到底部(叶子)计数,总计数的结果从底部到顶部计算
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: