LeetCode 0113.路径总和 II:两种方法解决

Posted Tisfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 0113.路径总和 II:两种方法解决相关的知识,希望对你有一定的参考价值。

【LetMeFly】113.路径总和 II:两种方法解决

力扣题目链接:https://leetcode.cn/problems/path-sum-ii/

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

 

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:

输入:root = [1,2,3], targetSum = 5
输出:[]

示例 3:

输入:root = [1,2], targetSum = 0
输出:[]

 

提示:

  • 树中节点总数在范围 [0, 5000]
  • -1000 <= Node.val <= 1000
  • -1000 <= targetSum <= 1000

前言

这道题类似于LeetCode 112. 路径总和,可参考题解https://letmefly.blog.csdn.net/article/details/125718939

方法一:广搜过程中记录path和sum

LeetCode 112. 路径总和类似,我们在广搜的时候,用vector<int>来记录路径上的节点的值即可。

  • 时间复杂度 O ( n 2 ) O(n^2) O(n2),其中 n n n是树的所有节点的个数。第 1 1 1维时间复杂度来自遍历(每个节点都遍历了 1 1 1次),第 2 2 2维时间复杂度来自答案的存放(把一个路径添加到答案中时路径的长度也为 O ( n ) O(n) O(n))
  • 空间复杂度 O ( n 2 ) O(n^2) O(n2),每个节点都需要用 O ( n ) O(n) O(n)的空间来记录 p a t h path path

AC代码

C++

typedef tuple<TreeNode*, vector<int>, int> pii;
class Solution 
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) 
        vector<vector<int>> ans;
        queue<pii> q;
        if (root)
            q.push(root, root->val, root->val);
        while (q.size()) 
            TreeNode* root;
            vector<int> path;
            int sum;
            tie (root, path, sum) = q.front();
            q.pop();
            if (!root->left && !root->right) 
                if (sum == targetSum) 
                    ans.push_back(path);
                
            
            if (root->left) 
                path.push_back(root->left->val);
                sum += root->left->val;
                q.push(root->left, path, sum);
                path.erase(--path.end());
                sum -= root->left->val;
            
            if (root->right) 
                path.push_back(root->right->val);
                sum += root->right->val;
                q.push(root->right, path, sum);
            
        
        return ans;
    
;

方法二:广搜过程中只记录sum

方法一的空间复杂度的来源主要是广搜过程中记录了路径path。我们可以优化这些空间:

用哈希表记录每个节点的父节点,再找到和为 t a r g e t S u m targetSum targetSum的叶节点后,从叶到根追溯到根节点即可获得路径。

这种方法相对于方法一会使用更少的空间,但是需要额外重新求一次路径path

  • 时间复杂度 O ( n 2 ) O(n^2) O(n2),其中 n n n是树的所有节点的个数。第 1 1 1维时间复杂度来自遍历(每个节点都遍历了 1 1 1次),第 2 2 2维时间复杂度来自答案的存放(把一个路径添加到答案中时路径的长度也为 O ( n ) O(n) O(n))
  • 空间复杂度 O ( n ) O(n) O(n),每个节点都需要用 O ( 1 ) O(1) O(1)的空间来记录 s u m sum sum,答案不计入空间复杂度中

AC代码

C++

typedef pair<TreeNode*, int> pii;
class Solution 
private:
    vector<vector<int>> ans;
    unordered_map<TreeNode*, TreeNode*> parent;

    void insertNewPath(TreeNode* leaf) 
        vector<int> path;
        while (true) 
            path.push_back(leaf->val);
            TreeNode* thisParent = parent[leaf];
            if (thisParent == leaf)
                break;
            leaf = thisParent;
                
        reverse(path.begin(), path.end());
        ans.push_back(path);
    

public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) 
        if (!root)
            return ;
        parent[root] = root;
        queue<pii> q;
        q.push(root, root->val);
        while (q.size()) 
            auto[root, sum] = q.front();
            q.pop();
            if (!root->left && !root->right) 
                if (sum == targetSum)
                    insertNewPath(root);
            
            if (root->left) 
                q.push(root->left, sum + root->left->val);
                parent[root->left] = root;
            
            if (root->right) 
                q.push(root->right, sum + root->right->val);
                parent[root->right] = root;
            
        
        return ans;
    
;

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/125739794

以上是关于LeetCode 0113.路径总和 II:两种方法解决的主要内容,如果未能解决你的问题,请参考以下文章

[leetcode] 113. 路径总和 II

[LeetCode] 113. 路径总和 II

LeetCode 113. 路径总和 II(Path Sum II)

Leetcode113. 路径总和 II

LeetCode 113 路径总和II

LeetCode Java刷题笔记—113. 路径总和 II