方法1:遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int pathSum(TreeNode root, int targetSum) {
if(root==null){
return 0;
}
return thisNodeSum(root,targetSum)+pathSum(root.left,targetSum)+pathSum(root.right,targetSum);
}
public int thisNodeSum(TreeNode root,int targetSum){
if(root==null){
return 0;
}
int a=targetSum-root.val;
int count=0;
if(a==0){
++count;
}
count+=(thisNodeSum(root.left,targetSum-root.val)+thisNodeSum(root.right,targetSum-root.val));
return count;
}
}
方法2:前缀和(空间换时间)
主要学习的题解:https://leetcode-cn.com/problems/path-sum-iii/solution/dui-qian-zhui-he-jie-fa-de-yi-dian-jie-s-dey6/
1 前缀和:一个节点的前缀和就是该节点到根之间的路径和
2 HashMap的key是前缀和, value是该前缀和的节点数量,记录数量是因为有出现复数路径的可能
3 本质还是空间换时间,保存各种前缀和出现的次数。
即:要寻找的前缀和=根节点到当前节点的路径和-targetSum
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
int wholeTargetSum;
Map<Integer,Integer> map;
public int pathSum(TreeNode root, int targetSum) {
wholeTargetSum=targetSum;
map=new HashMap<>();
map.put(0,1); //十分重要的一行,不然就不能从根节点开始算了
return dfs(root,0);
}
public int dfs(TreeNode root,int pre){
if(root==null){
return 0;
}
int pathSum=pre+root.val; //获取节点到当前节点root的路径和pathSum
int needPrefix=pathSum-wholeTargetSum; //得到需要的前缀和needPrefix
int count=map.getOrDefault(needPrefix,0); //得到needPrefix对应次数
/*添加该前缀和到map中,给子节点使用
这行代码不能放在 int count=map.getOrDefault(needPrefix,0); 之前,因为路径不能不包括任何节点
*/
map.put(pathSum,map.getOrDefault(pathSum,0)+1);
count+=dfs(root.left,pathSum);
count+=dfs(root.right,pathSum);
map.put(pathSum,map.get(pathSum)-1); //去除这个前缀和对应的次数
return count;
}
}
// class Solution {
// Map<Integer, Integer> prefixMap;
// int target;
// public int pathSum(TreeNode root, int sum) {
// prefixMap = new HashMap<>();
// target = sum;
// prefixMap.put(0, 1);
// return recur(root, 0);
// }
// private int recur(TreeNode node, int curSum) {
// if(node == null) {
// return 0;
// }
// int res = 0;
// curSum += node.val;
// res += prefixMap.getOrDefault(curSum - target, 0);
// prefixMap.put(curSum, prefixMap.getOrDefault(curSum, 0) + 1);
// int left = recur(node.left, curSum);
// int right = recur(node.right, curSum);
// res = res + left + right;
// prefixMap.put(curSum, prefixMap.get(curSum) - 1);
// return res;
// }
// }