113.路径总和 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)$,其中$n$是树的所有节点的个数。第$1$维时间复杂度来自遍历(每个节点都遍历了$1$次),第$2$维时间复杂度来自答案的存放(把一个路径添加到答案中时路径的长度也为$O(n)$)
  • 空间复杂度$O(n^2)$,每个节点都需要用$O(n)$的空间来记录$path$

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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。我们可以优化这些空间:

用哈希表记录每个节点的父节点,再找到和为$targetSum$的叶节点后,从叶到根追溯到根节点即可获得路径。

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

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

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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


113.路径总和 II
https://blog.letmefly.xyz/2022/07/12/LeetCode 0113.路径总和II/
作者
Tisfy
发布于
2022年7月12日
许可协议