原题链接
一. 题目描述
给定一个不含重复数字的数组 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]]
提示:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums
中的所有整数 互不相同
二. 解题思路
本题就是一个排列问题,给定你一个数组,要求你输出该数组中元素的所有排列情况。这里我们使用的方法还是回溯,通过将数组中的元素以不同的顺序前后分别加入到path 数组中从而形成不同的排列情况,还是简单的三件套,你还记得吗?
1. 确定递归参数:首先nums 基础数组必不可少,再有就是startindex 记录遍历位置,其实这里并不需要,因为我们是通过不同的顺序将元素加入到path 中,所以每一次都从开始位置即可,不过得定义一个used 数组用来记录当前的元素是否已经被加入到path 中。
2. 确定递归终止条件:由于是排列问题,所以每一个排列的大小都和数组nums 的大小是相同的,所以当path 的大小等于nums 大小的时候就可以收集结果并return 了。
3. 单层递归:每一次都从第一位开始, 判断是否被加入,如果已经被加入就直接跳过,如果没有就加入,然后进行递归,在递归完之后回溯进行下一次。
具体的路线图大家可以看一下下面这个代码随想录的示例图(偷过来的):
话不多说!!!上代码!!
三. 代码
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void back(vector<int>& nums, vector<bool> used){
if(path.size() == nums.size()){
res.push_back(path);
return;
}
for(int i = 0; i < nums.size(); i++){
if(used[i]) continue;
else{
path.push_back(nums[i]);
used[i] = true;
back(nums, used);
used[i] = false;
path.pop_back();
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> used(nums.size(), false);
back(nums, used);
return res;
}
};
四. 总结
本题和之前做过的有一些不一样,不过思路都是大差不差的,大家一定要多思考,实在不会就去找个纸笔盯着代码一行一行把每一步的执行结果写下来,这样会清晰很多。千万不能只看一眼感觉自己会了就不去写了,或者像一些人一样(咳咳,当然不是我啊)直接抄上之后看都不看。加油!!!
时间复杂度:O(n!);
空间复杂度:O(n)。