写在前面
本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……
专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:
- Tag:介绍本题牵涉到的知识点、数据结构;
- 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
- 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
- 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
- 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。
Tag
【回溯】【全排列】
题目来源
![](https://img-blog.csdnimg.cn/img_convert/a4b25f660aaccd11d205d3e18902f643.png)
解题思路
方法一:回溯
思路
全排列中的元素是有顺序的,[1,2,3] 和 [3,2,1] 在组合中是属于同一个组合的,但是在排列中是属于不同排列的。
设数组 n u m s nums nums 的长度为 n n n,全排列问题就是使用 n u m s nums nums 中的 n n n个数字将这 n n n 个位置填满。
利用回溯思想枚举所有全排列。使用递归实现,递归出口为已经找到了长度为 n
的全排列。
枚举所有可以用到的数,如果当前这个数没有被使用过,则可以用在当前这个位置,然后递归选择下一个数,记得先要标记当前数已经被使用了。当使用完这个数后记得恢复现场,一边回溯使用这个数。
代码
class Solution {
private:
vector<vector<int>> res;
vector<int> tmp;
vector<int> isVisted;
void dfs(vector<int>& nums, int idx) {
if (idx == 0) {
res.push_back(tmp);
return;
}
for (int i = 0; i < nums.size(); ++i) {
if (!isVisted[i]) {
isVisted[i] = 1;
tmp.push_back(nums[i]);
dfs(nums, idx - 1);
tmp.pop_back();
isVisted[i] = 0;
}
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
int n = nums.size();
isVisted.resize(n);
dfs(nums, n);
return res;
}
};
复杂度分析
时间复杂度: O ( n ⋅ n ! ) O(n \cdot n!) O(n⋅n!),分析。
空间复杂度: O ( n ) O(n) O(n)。
写在最后
如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。
最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。