写在前面
本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……
专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:
- Tag:介绍本题牵涉到的知识点、数据结构;
- 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
- 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
- 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
- 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。
Tag
【回溯】【组合】【递归】
题目来源
![](https://img-blog.csdnimg.cn/img_convert/4d3ed3c91207a45f3e932fb8ad21927b.png)
解题思路
方法一:回溯
思路
这题目就是枚举所有可能,看哪一种可能求和为 target
。
因为选择某个元素的时候就会让 target 减去这个数,因而最后 target == 0
时表示已经选择的元素可以求和为 traget
,即为递归出口。
需要注意的是每个元素可以选择多次,因此选了这个元素,下个元素仍然可以选择这个元素。
d
f
s
dfs
dfs 参数列表中的 i
表示开始选择元素的下标,这样做可以去除重复的组合。如果不增加这个参数,示例 1 中就会有 [2,2,3],[2,3,2],[3,2,2]
这个样的重复组合。
代码
class Solution {
private:
vector<vector<int>> res;
vector<int> tmp;
void dfs(vector<int>& candidates, int target, int i) {
if (target == 0) {
res.push_back(tmp);
return;
}
if (target < 0) { // 剪枝
return;
}
for (int k = i; k < candidates.size(); ++k) {
tmp.push_back(candidates[k]);
dfs(candidates, target - candidates[k], k); // 每个元素可以选择多次
tmp.pop_back();
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
dfs(candidates, target, 0);
return res;
}
};
复杂度分析
时间复杂度: O ( S ) O(S) O(S), S S S 为所有可行解的长度之和。见官方题解 分析.
空间复杂度: O ( t a r g e t ) O(target) O(target)。除答案数组外,空间复杂度取决于递归的栈深度,在最差情况下需要递归 O ( t a r g e t ) O(target) O(target) 层。
写在最后
如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。
最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。