两层dfs 第一层dfs找根节点,第二层dfs从根节点开始找路径
时间复杂度O(n2)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
void dfs(struct TreeNode* proot,int sum,int*ans,int targetSum)
{
if(sum==targetSum)
(*ans)++;
if(proot->left!=NULL)
dfs(proot->left,sum+proot->left->val,ans,targetSum);
if(proot->right!=NULL)
dfs(proot->right,sum+proot->right->val,ans,targetSum);
return;
}
void dfs_out(struct TreeNode* proot,int* ans,int targetSum)
{
if(proot==NULL)
return;
dfs(proot,proot->val,ans,targetSum);
dfs_out(proot->left,ans,targetSum);
dfs_out(proot->right,ans,targetSum);
return;
}
int pathSum(struct TreeNode* root, int targetSum){
int ans=0;
dfs_out(root,&ans,targetSum);
return ans;
}
若用dfs的返回值表示在此根节点下满足条件的路径,用dfs_out的返回值表示所有的路径数,则ans可以省去,同时若用delta表示当前的和与targetsum的差值,则sum也可以省去
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int dfs(struct TreeNode* proot,int delta)
{
int ans=0;
if(delta==0)
ans++;
if(proot->left)
ans+=dfs(proot->left,delta-proot->left->val);
if(proot->right)
ans+=dfs(proot->right,delta-proot->right->val);
return ans;
}
int dfs_out(struct TreeNode* proot,int targetSum)
{
if(proot==NULL)
return 0;
int ans=0;
ans+=dfs(proot,targetSum-proot->val);
ans+=dfs_out(proot->left,targetSum);
ans+=dfs_out(proot->right,targetSum);
return ans;
}
int pathSum(struct TreeNode* root, int targetSum){
return dfs_out(root,targetSum);
}
同时也可用pathSum函数来代替dfs_out函数
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int dfs(struct TreeNode* proot,int delta)
{
int ans=0;
if(delta==0)
ans++;
if(proot->left)
ans+=dfs(proot->left,delta-proot->left->val);
if(proot->right)
ans+=dfs(proot->right,delta-proot->right->val);
return ans;
}
int pathSum(struct TreeNode* root, int targetSum){
if(root==NULL)
return 0;
int ans=0;
ans+=dfs(root,targetSum-root->val);
ans+=pathSum(root->left,targetSum);
ans+=pathSum(root->right,targetSum);
return ans;
}
还可以进行优化,因为当用dfs计算一段路径上的和的时候是很容易发生重复计算的,可以用前缀和进行优化
官方题解
代码中的map实际上存储的是当前路径上的前缀和,所以当回溯的时候,要把当前结点的前缀和在map中去掉,因为不是下一条路径上的了
mp[0]=1实际上是指从结点pk到根节点root这条路径符合条件,这如果要用前缀和的形式pre[pk]-pre[x]的话x就是根节点的“前一个结点”,“前一个结点”的前缀和必然是0,所以前缀和为0的结果必然有1个
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
unordered_map<long long,int> mp;
int dfs(TreeNode* root,int curr,int targetSum)
{
if(root==NULL)
return 0;
int ans=0;
curr=curr+root->val;
if(mp.count(curr-targetSum))
{
ans+=mp[curr-targetSum];
}
mp[curr]++;
ans+=dfs(root->left,curr,targetSum);
ans+=dfs(root->right,curr,targetSum);
mp[curr]--;
return ans;
}
int pathSum(TreeNode* root, int targetSum) {
mp[0]=1;
return dfs(root,0,targetSum);
}
};
时间复杂度O(n)