LeetCode/路径总和
1. 树中是否存在根节点到叶子节点的路径
class Solution {
public:
bool hasPathSum(TreeNode *root, int sum) {
if (root == nullptr) {
return false;
}
if (root->left == nullptr && root->right == nullptr) {
return sum == root->val;
}
return hasPathSum(root->left, sum - root->val) ||
hasPathSum(root->right, sum - root->val);
}
};
2. 找出所有从根节点到叶子节点路径
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(!root) return {};
vector<int> cur;
backtrack(root,targetSum,cur);
return res;
}
//回溯法
void backtrack(TreeNode* root,int targetSum,vector<int>& cur){
cur.push_back(root->val);//做选择
if(!root->left&&!root->right&&targetSum==root->val){ res.push_back(cur);
cur.pop_back();return;}
if(root->left!=nullptr) backtrack(root->left,targetSum-root->val,cur);
if(root->right!=nullptr) backtrack(root->right,targetSum-root->val,cur);
cur.pop_back();//撤销选择
}
};
3. 所有路径数目
//两重递归
class Solution {
public:
int pathSum(TreeNode* root, int targetSum) {
if(!root) return 0;
int count = 0;//以root为初始点的路径数
int left = 0 ;int right = 0;
left = pathSum(root->left,targetSum);//以左节点为根节点
right = pathSum(root->right,targetSum);//以右节点为根节点
dfs(root,targetSum,count);//以当前节点为根节点
return left+right+count;
}
//每个根节点共用一个count
void dfs(TreeNode* root, long targetSum,int &count){
if(targetSum-root->val==0) count++; //不中断直至遍历完
if(root->left)
dfs(root->left,targetSum-root->val,count);//寻找路径
if(root->right)
dfs(root->right,targetSum-root->val,count);//寻找路径
}
};
用哈希表记录前缀和,即可递归一趟,减少重复计算 对于每个递归路径,都相当于求一个一维数组连续序列和等于指定值
class Solution {
public:
int pathSum(TreeNode* root, int sum)
{
int res = 0; // 满足条件的路径数量
prefix[0] = 1; // 前缀和为0的路径只有一条:哪个节点都不选
dfs(root, sum, 0, res);
return res;
}
private:
unordered_map<int, int> prefix; // <前缀和,其出现次数>
void dfs(TreeNode* root, int sum, int cur_sum, int& res)
{
if (!root) return;
cur_sum += root->val; // 更新前缀和
// 当前路径中存在以当前节点为终点的和为sum的子路径
if (prefix.find(cur_sum - sum) != prefix.end())
res += prefix[cur_sum - sum];
prefix[cur_sum]++; // 做选择
dfs(root->left, sum, cur_sum, res); // 在其左子树中递归寻找
dfs(root->right, sum, cur_sum, res);// 在其右子树中递归寻找
prefix[cur_sum]--; // 撤销选择
}
};