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.
* 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写的思路,我也研读了一下。
希望我的评论可以帮助理解这个解决方案。
1前缀存储递归中从根节点到当前节点的总和
2在到达当前节点之前,地图存储<前缀和,频率>对。我们可以想象一条从根节点到当前节点的路径。从路径中间的任何节点到当前节点的总和=从根节点到当前节点的总和与中间节点的前缀总和之差。
3我们正在寻找总和达到给定目标值的连续节点,这意味着2.中讨论的差异应该等于目标值。另外,我们需要知道有多少差异等于目标值。
4这里是map。map存储当前节点路径中所有可能和的频率。如果当前总和与目标值之间的差异存在于映射中,那么必须在路径中间存在节点,使得从该节点到当前节点的总和等于目标值。
5请注意,中间可能有多个节点满足4中讨论的内容。map中的频率用于帮助解决此问题。
6因此,在每一次递归中,map都会存储我们需要计算总计达到目标的范围数的所有信息。请注意,每个范围从中间节点开始,由当前节点结束。
7要获得路径总数,我们将树中EACH节点结束的有效路径数加起来。
8每次递归都会返回以当前节点为根的子树中的有效路径总数。这笔款项可分为三部分:
- 以当前节点的左侧子节点为根的子树中的有效路径总数
- 以当前节点的右侧子节点为根的子树中的有效路径总数
- 当前节点结束的有效路径数量
这个解决方案有趣的部分是前缀从顶部(根)到底部(叶子)计数,总计数的结果从底部到顶部计算
题目大意:
给定一颗二叉树,每个节点包含一个整数值。计算所有和为给定值的路径个数。路径不一定以根开始,也不一定以叶子结束,但是必须自上而下(从双亲结点到孩子节点)树节点个数不超过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每次递归都会返回以当前节点为根的子树中的有效路径总数。这笔款项可分为三部分:
- 以当前节点的左侧子节点为根的子树中的有效路径总数
- 以当前节点的右侧子节点为根的子树中的有效路径总数
- 当前节点结束的有效路径数量
这个解决方案有趣的部分是前缀从顶部(根)到底部(叶子)计数,总计数的结果从底部到顶部计算
相关文章推荐
- LeetCode 437 Path Sum III (DFS)
- leetcode(437):Path Sum III
- LeetCode 437 Path Sum III 题解
- LeetCode "437. Path Sum III"
- LeetCode 437 Path Sum III
- leetcode-437-Path Sum III
- LeetCode 437 Path Sum III
- [python]leetcode(437). Path Sum III
- LeetCode 437. Path Sum III (路径之和之三)
- 437. Path Sum III
- LeetCode 437. Path Sum III (STL map前缀和)
- [leetcode]437. Path Sum III
- 437. Path Sum III
- LeetCode -- Path Sum III分析及实现方法
- 437. Path Sum III
- leetcode 437. Path Sum III(路径和)(DFS)
- 437. Path Sum III
- [437]. Path Sum III,[687]. Longest Univalue Path
- LeetCode——Path Sum III
- 【LeetCode】Path Sum III 解题报告