LeetCode HOT100 - 路径总和 III
首先这题的路径是限制了从一个节点到它子节点这样的简单路径,而不是一般的例如树的直径的那种形式
比较容易想到的就是自底向上传递信息,或者就是说 dfs 先获取左子树和右子树的信息,然后计算答案
进而考虑我们需要什么信息,因为路径是简单链,所以就是子树那条链上的值的后缀和,每一轮向上传递,实际就是在子节点所有可能的情况上加上当前的目标值
并且在传递时更新下答案
/**
* 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) {}
* };
*/
using i64 = long long;
class Solution {
public:
int pathSum(TreeNode* root, int targetSum) {
int ans = 0;
auto dfs = [&](auto self, TreeNode* x) -> vector<i64> {
vector<i64> res;
if (!x) {
return res;
}
auto l = self(self, x->left);
auto r = self(self, x->right);
for (int i = 0; i < l.size(); i++) {
l[i] += x->val;
res.emplace_back(l[i]);
if (l[i] == targetSum) {
ans++;
}
}
for (int i = 0; i < r.size(); i++) {
r[i] += x->val;
res.emplace_back(r[i]);
if (r[i] == targetSum) {
ans++;
}
}
res.emplace_back(x->val);
if (x->val == targetSum) {
ans++;
}
return res;
};
dfs(dfs, root);
return ans;
}
};
当然我当时这么写一部分是一开始以为路径不是这样的必需向下的
那么考虑到这种前缀的形式的话,实际上可以通过类似于前缀和加回溯的搜索来做,也就是
using i64 = long long;
class Solution {
public:
int pathSum(TreeNode* root, int targetSum) {
unordered_map<i64, int> cnt;
cnt[0] = 1;
auto dfs = [&](auto self, TreeNode* x, i64 sum) -> int {
if (!x) return 0;
sum += x->val;
int res = cnt[sum - targetSum];
cnt[sum]++;
res += self(self, x->left, sum) + self(self, x->right, sum);
cnt[sum]--;
return res;
};
return dfs(dfs, root, 0);
}
};

浙公网安备 33010602011771号