题目链接:leetcode.
如果只能从根节点开始
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
vector<vector<int>> ans;
vector<int> tmp;
void dfs(TreeNode* root, int sum)
{
if(root)
{
sum -= root -> val;
tmp.push_back(root -> val);
if(root -> left)
{
dfs(root -> left, sum);
}
tmp.pop_back();
if(root -> right)
{
dfs(root -> right, sum);
}
}
if(sum == 0)
{
ans.push_back(tmp);
}
}
public:
int pathSum(TreeNode* root, int sum) {
if(root == nullptr)
return 0;
dfs(root, sum);
return ans.size();
}
};
为了将其扩展到从任何地方开始的路径,我们可以对所有节点暴力重复此过程。
/*
执行用时:20 ms, 在所有 C++ 提交中击败了44.78%的用户
内存消耗:23.2 MB, 在所有 C++ 提交中击败了8.56%的用户
*/
class Solution {
vector<vector<int>> ans;
vector<int> tmp;
void dfs(TreeNode* root, int sum)
{
if(root)
{
sum -= root -> val;
tmp.push_back(root -> val);
if(root -> left)
{
dfs(root -> left, sum);
}
tmp.pop_back();
if(root -> right)
{
dfs(root -> right, sum);
}
}
if(sum == 0)
{
ans.push_back(tmp);
}
}
public:
int pathSum(TreeNode* root, int sum) {
if(root == nullptr)
return 0;
dfs(root, sum);
int t = pathSum(root -> left, sum) + pathSum(root -> right, sum);
return ans.size();
}
};
对暴力进行优化,使用哈希表记录当前访问到的前缀和(因为查找时间为O(1))
如果当前的前缀和减去要求的sum在哈希表中存在,说明是有这样的路径刚好为sum的
/*
[1]
0
93 / 114 个通过测试用例
[0,1,1]
1
96 / 114 个通过测试用例
*/
class Solution {
int ans;
void dfs(TreeNode* root,unordered_map<int, int>& Hash, int sum, int cur)
{
if(root != nullptr)
{
cur += root -> val;
Hash[cur]++;
if(Hash[cur - sum])
{
ans++;
}
dfs(root -> left, Hash, sum, cur);
dfs(root -> right, Hash, sum, cur);
}
}
public:
int pathSum(TreeNode* root, int sum) {
if(root == nullptr)
return 0;
unordered_map<int, int> Hash;
Hash[0] = 1;//前缀和为0的有一条(即根节点root)
dfs(root, Hash, sum, 0);
return ans;
}
};
不明白,我的回溯总是会出错,那就像题解那样写成递归吧
/*
执行用时:12 ms, 在所有 C++ 提交中击败了89.10%的用户
内存消耗:19.8 MB, 在所有 C++ 提交中击败了15.36%的用户
*/
class Solution {
int dfs(TreeNode* root,unordered_map<int, int>& Hash, int sum, int cur)
{
if(root == nullptr)
{
return 0;
}
int ans = 0;
cur += root -> val;
if(Hash[cur - sum])
{
ans+= Hash[cur - sum];
}
Hash[cur]++;
ans += dfs(root -> left, Hash, sum, cur);
ans += dfs(root -> right, Hash, sum, cur);
Hash[cur]--;//因为传的是引用,不改回去会影响上一层
return ans;
}
public:
int pathSum(TreeNode* root, int sum) {
if(root == nullptr)
return 0;
unordered_map<int, int> Hash;
Hash[0] = 1;//前缀和为0的有一条(即根节点root)
return dfs(root, Hash, sum, 0);
}
};