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]--;                  // 撤销选择
    }
};
posted @ 2022-07-25 21:19  失控D大白兔  阅读(25)  评论(0编辑  收藏  举报