46. 全排列
题意:
给定一个不含重复数字的数组
nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1]
输出:[[1]]
解题思路:
利用递归加回溯,因为删除数组时间复杂度太大,所以需要加上标记数组来完成.
问 答 递归结束条件 如果路劲长度为nums.size(),就说明全部数字都有了,就直接添加进结果并返回 单层递归 遍历nums数组,然后选择nums数组里面一个没有打上标记的数开始递归.直到遍历结束即可
- 总体就是外层遍历nums数组,如果没有标记说明path里面还没有改数字,就内层递归继续选择下一个数字
class Solution {
public:
vector<vector<int>> res;
//用vector<bool> flag(6,false)无法通过,在vs可以
vector<bool> flag{false,false,false,false,false,false};
//K是数组长度,我用一个参数来存储,这里的path我用的引用,等下需要显性回溯
void findPer(vector<int>nums, vector<int>&path,int k)
{
//如果长度等于数组长度,说明添加全部数字了
if (path.size() == k)
{
res.push_back(path);
return;
}
//如果还没有添加完,就遍历找到没有添加的元素添加
for (int i = 0; i < k; i++)
{
//如果找到了没有标记的,说明还没添加
if (flag[i] != true)
{
flag[i] = true;
path.push_back(nums[i]);
findPer(nums, path, k);
//回溯
path.pop_back();
flag[i] = false;
}
}
}
vector<vector<int>> permute(vector<int>& nums)
{
//存储路劲
vector<int>path;
findPer(nums, path,nums.size());
return res;
}
};
总结:
本体的难度在于如果使用隐性回溯会触发死循环.一直都是前K个,因为回溯是就把标记打回去了.所以比较难处理,直接用显性回溯即可