leetcode437 路和总径3
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例 1:
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。
一、递归(时间复杂度高)
class Solution {
int res=0;
//前序遍历每个二叉树节点
public int pathSum(TreeNode root, int targetSum) {
if(root==null)return 0;
curNodeSum(root,targetSum);
pathSum(root.left,targetSum);
pathSum(root.right,targetSum);
return res;
}
//针对每个节点为首节点求出一连串和为targetSum的子树有多少对
public void curNodeSum(TreeNode root,int targetSum){
if(root==null){
return;
}
targetSum=targetSum-root.val;
if(targetSum==0){
res++;
}
curNodeSum(root.left,targetSum);
curNodeSum(root.right,targetSum);
}
}
二、前缀和
class Solution{
//前缀和思想: Key:和为key value:和为key的路径有多少条
HashMap<Integer,Integer> map=new HashMap<>();
public int pathSum(TreeNode root,int targetSum){
if(root==null)return 0;
map.put(0,1);
return getSum(root,targetSum,0);
}
//这边必须是前序遍历
public int getSum(TreeNode root,int targetSum,int sum){
if(root==null)return 0;
int res=0;
//求出到当前节点的路径和
int curPathSum=sum+root.val;
//看之前是否存在以curPathSum-targetSum为key的前缀和路径
res+=map.getOrDefault(curPathSum-targetSum,0);
//保存当前前缀和数量
map.put(curPathSum,map.getOrDefault(curPathSum,0)+1);
res+=getSum(root.left,targetSum,sum+root.val);
res+=getSum(root.right,targetSum,sum+root.val);
//进行回溯
map.put(curPathSum,map.get(curPathSum)-1);
return res;
}
}