LeetCode 437. Path Sum III
437. Path Sum III
Description Submission Solutions
- Total Accepted: 18367
- Total Submissions: 47289
- Difficulty: Easy
- Contributors: Stomach_ache
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.
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
Subscribe to see which companies asked this question.
给定一颗二叉树,找到二叉树中从上往下所有的和值为目标值的节点序列。不要求必须从根节点开始到叶子结点。
【思路】
1. 我们可以遍历二叉树的每一个结点,搜索从这个节点出发的所有满足条件的路径的数目。
这种方法以某种顺序遍历一棵树中的所有节点,然后计算从这个节点出发的满足条件的路径数。遍历二叉树的时间复杂度为O(N),对于每一个节点,需要以它为根节点找到所有的符合条件的路径,则综合来看时间复杂度为O(N2)。递归栈的最大深度为logN,因此空间复杂度为O(logN)。
2. So the idea is similar as Two sum, using HashMap to store ( key : the prefix sum, value : how many ways get to this prefix sum) , and whenever reach a node, we check if prefix sum - target exists in hashmap or not, if it does, we added up the ways of prefix sum - target into res.
For instance : in one path we have 1,2,-1,-1,2, then the prefix sum will be: 1, 3, 2, 1, 3, let's say we want to find target sum is 2, then we will have{2}, {1,2,-1}, {2,-1,-1,2} and {2}ways.
For instance : in one path we have 1,2,-1,-1,2, then the prefix sum will be: 1, 3, 2, 1, 3, let's say we want to find target sum is 2, then we will have{2}, {1,2,-1}, {2,-1,-1,2} and {2}ways.
这是discuss里的一个比较好的方法,时间复杂度得到了优化。
这个方法的思路是保存从根节点到达当前节点的prefix sum。比如到达当前节点经过的节点val为 1,2,-1,-1,2,那么prefix为1,3,2,1,3. 计算当前节点的prefix sum,然后在前面的所有prefix sum中查找是否存在curSum - target,如果存在,则证明存在这样的点,从这点出发到达当前节点的值正好为target。
通过上图,我们明白了这个算法的思想。这个算法通过一个hashmap来保存这样的prefix sum信息。那么多二叉树的分叉,是否需要为每一个分支建立一个HashMap呢?我们并不需要这样做,而是采用回溯的做法,如果当前节点的所有的路径都处理完毕了,则把该节点从HashMap中删除,转而去处理别的节点。在初始的时候我们把(0,1)加入HashMap。这是为了那些curSum正好target情况的出现。
【java代码1】
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 public int pathSum(TreeNode root, int sum) { 12 if(root == null) return 0; 13 int res = pathNum(root, sum); 14 15 if(root.left != null) res += pathSum(root.left, sum); 16 if(root.right != null) res += pathSum(root.right, sum); 17 18 return res; 19 } 20 21 public int pathNum(TreeNode root, int sum) { 22 if(root == null) return 0; 23 int res = 0; 24 if(root.val == sum) res++; 25 if(root.left != null) res += pathNum(root.left, sum-root.val); 26 if(root.right != null) res += pathNum(root.right, sum-root.val); 27 28 return res; 29 } 30 }
【java代码2】
1 public class Solution { 2 public int pathSum(TreeNode root, int sum) { 3 HashMap<Integer, Integer> preSum = new HashMap<>(); 4 preSum.put(0, 1); 5 return helper(root, 0, sum, preSum); 6 } 7 8 public int helper(TreeNode root, int curSum, int target, HashMap<Integer, Integer> preSum) { 9 if(root == null) return 0; 10 11 curSum += root.val; 12 int res = preSum.getOrDefault(curSum-target, 0); 13 //把当前节点加入到路径中 14 preSum.put(curSum, preSum.getOrDefault(curSum, 0) + 1); 15 //处理该节点的左子树和右子树 16 res += helper(root.left, curSum, target, preSum); 17 res += helper(root.right, curSum, target, preSum); 18 //回溯。把已经处理完毕的当前节点从路径中清除 19 preSum.put(curSum, preSum.get(curSum) - 1); 20 21 return res; 22 } 23 }