版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/luo870604851/article/details/88914894
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
首先想到的递归解法:直接递归
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
if(nums.empty())
return {};
if(nums.size()==1)//只有一个数,直接返回
{
res.push_back(nums[0]);
result.push_back(res);
return result;
}
for(int i=0;i<nums.size();i++)//对于每个数,先剔除它,递归剔除后的数组,然后再加上
{
vector<int> backup(nums);//不能直接修改原数组,传备份的数组
vector<vector<int>> receive;//接收传回
auto it=backup.begin();
int tmp=backup[i];//保存第i个数,递归后续加入
backup.erase(it+i);//剔除第i个数
receive=permute(backup);//递归剔除后的数组
for(auto& r:receive)//对于每个回传的数组集
{
r.push_back(tmp);//先逐个加入被剔除的数
result.push_back(r);//存入结果
}
}
return result;
}
};
由于在递归和循环过程中都需要创造原数组的备份和数据剔除,导致时间复杂度和空间复杂度很大。
其实可以不用遍历数组中的每一个数,而是逐个交换第一个和数组中的每一个数(含第一个),然后对剩下的数进行全排列递归,也不用剔除固定的数再进行递归,可以引入临时变量,让它总是从当前数的下一个数开始递归剩余的数。从而免去了剔除带来的时间消耗和备份带来的空间消耗。
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
permuteDFS(nums,result);
return result;
}
void permuteDFS(vector<int>& num,vector<vector<int>>& result,int k=0)
{
if(k==num.size())
result.push_back(num);
for(auto i=k;i<num.size();i++)
{
swap(num[k],num[i]);
permuteDFS(num,result,k+1);从当前数的下一个开始递归即可
swap(num[i],num[k]);//恢复成原数组
}
}
};