leetcode 437:路径总和
给定一个二叉树的根节点 root
,和一个整数 targetSum
,求该二叉树里节点值之和等于 targetSum
的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例 1:
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。
示例 2:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3
提示:
- 二叉树的节点个数的范围是
[0,1000]
-109 <= Node.val <= 109
-1000 <= targetSum <= 1000
Related Topics
树
深度优先搜索
二叉树
思路1:深度优先遍历
从每一个节点计算路径和,计算符合的数量。
class Solution {
private int count = 0;
public int pathSum(TreeNode root, int targetSum) {
if(root == null){
return count;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
TreeNode p = queue.poll();
dfs(p,targetSum);
if(p.left!=null){
queue.offer(p.left);
}
if(p.right != null){
queue.offer(p.right);
}
}
return count;
}
public void dfs(TreeNode root,int targetSum){
if(root == null){
return;
}
if(root.val == targetSum){
count++;
}
dfs(root.left,targetSum-root.val);
dfs(root.right,targetSum-root.val);
}
}
解答成功:
执行耗时:26 ms,击败了41.62% 的Java用户
内存消耗:41.3 MB,击败了6.05% 的Java用户
思路2:前缀和
前缀和:从根节点到每一个节点的路径和。
思路:
- 利用先序遍历,记录根节点root到当前节点p除了当前节点以外所有节点的前缀和,在已保存的前缀和中查找是否有前缀和刚好等于当前节点的前缀和减去targetNum。(当前节点的前缀和-之前节点的前缀和 = targetNum)
代码思路:
- 保存空路径。
- 进行递归。
- 计算当前节点的前缀和。
- 判断之前是否有前缀符合。(当前节点的前缀-之前的前缀= targetSum)
- 把当前节点加入map。
- 递归左右子树。
- 回溯。
class Solution {
private HashMap<Long,Integer> map = new HashMap<>();
private int count = 0;
public int pathSum(TreeNode root, int targetSum) {
map.put(0L,1);
dfs(root,0,targetSum);
return count;
}
//curr表示前缀和
public void dfs(TreeNode root,long curr,int targetSum){
if(root == null){
return;
}
//计算当前节点的前缀和
curr += root.val;
//当前节点的前缀和-之前节点的前缀和 == targetSum
//之前的前缀和在map中
count += map.getOrDefault(curr-targetSum,0);
//把当前节点加入map 进行递归
map.put(curr,map.getOrDefault(curr,0)+1);
dfs(root.left,curr,targetSum);
dfs(root.right,curr,targetSum);
map.put(curr,map.getOrDefault(curr,0)-1);
}
}
解答成功:
执行耗时:2 ms,击败了100.00% 的Java用户
内存消耗:40.8 MB,击败了38.60% 的Java用户