46. Permutations
问题描述
Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路
- 思路1
- m个不同数的所有排列,可以这么得到:首先得到前m-1个数的所有排列,然后将第m个数分别插入到每种排列的不同位置得到。如果前m-1个数的所有排列数为 cntm−1 , 则m个数的所有排列数 cntm=cntm−1×m
- 由此思路可采用递归的方法。
- 思路2
- 可先实现nextPermutation()来获取当前排列的下一个排列
- 设置初始排列和终止条件,则可由nextPermutation获得所有排列
- 思路3
- 可采用深度优先搜索来实现
算法描述1:递归
- 如果nums的长度为1,则将nums入栈result,返回result。
- 设nums的长度为m,截取前m-1个数nums_tmp,并保留最后一个数为num_new。
- 递归执行permute(result_tmp),获得前m-1个数的所有排列result_tmp
- 遍历result_tmp:i
- 每个排列的长度为m-1,由m个位置可以插入num_new,遍历插入,并将新的排列压栈result
- 得到m个数的所有排列,返回result。
实现代码1:递归
vector<vector<int>> permute(vector<int>& nums)
{
vector<vector <int> > result;
if(nums.size() == 1)
{
vector<int> tmp;
tmp.push_back(nums[0]);
result.push_back(tmp);
return result;
}
vector<int> nums_tmp;
nums_tmp.assign(nums.begin(),prev(nums.end()));
int num_new= *prev(nums.end());
vector<vector<int>> result_tmp;
result_tmp = permute(nums_tmp);
const int m = result_tmp.size();
const int n = result_tmp[0].size();
for(int i =0; i< m;i++)
{
for (int j = 0; j <= n;j++)
{
vector<int> tmp2=result_tmp[i];
tmp2.insert(tmp2.begin()+j,num_new);
result.push_back(tmp2);
}
}
return result;
}
算法描述2
- 如果nums为空,则返回空
- 设nums的长度为m,计算所有排列的数 m!
- 遍历m!次,调用nextPermutation(),得到下一个排列,并压栈result
- 返回result
注:nextPermutation()的实现在 nextPermutation 下一个排列中可以查看
代码实现2
vector<vector<int>> permute(vector<int>& nums)
{
vector<vector<int>> result;
if(nums.empty())
return result;
sort(nums.begin(),nums.end());
long m=factorial(nums.size());
for(int i=0;i<m;i++)
{
result.push_back(nums);
nextPermutation(nums);
}
return result;
}
bool Solution::nextPermutation2(vector<int>& nums)
{
if(nums.size()==0)
return false;
for(int i=nums.size()-2;i>=0;i--)
{
int min=INT_MAX;
int k=-1;
for(int j=nums.size()-1;j>i;j--)
{
if(nums[i]<nums[j] && nums[j]< min)
{
k=j;
min=nums[j];
}
}
if(k != -1)
{
int temp=nums[k];
nums[k]=nums[i];
nums[i]=temp;
sort(nums.begin()+i+1,nums.end());
return false;
}
}
// 如果是最大时
for(int i=0;i<nums.size()/2;i++)
{
int temp=nums[i];
nums[i]=nums[nums.size()-i-1];
nums[nums.size()-i-1]=temp;
}
return true;
}
算法描述3:深度优先搜索
- 如果为空,则返回空
- 将数组排序
- 定义初始路径path,然后调用dps_permute(nums,path,result)实现
- 如果path的长度为nums的长度,则将path压栈result,并返回
- 遍历数组nums:i
- 在path中查找i,如果不存在:
- 将i压栈path,递归调用dps_permuter(nums)
- path出栈
- 在path中查找i,如果不存在:
- 返回result
实现代码3
vector<vector<int>> Solution::permute(vector<int>& nums)
{
vector<vector<int>> result;
if(nums.empty())
return result;
sort(nums.begin(),nums.end());
vector<int> path;
dps_permute(nums,path,result);
return result;
}
void Solution::dps_permute(vector<int>& nums, vector<int>& path, vector<vector<int>>& result)
{
if(path.size() == nums.size())
{
result.push_back(path);
return;
}
for(auto i: nums)
{
auto pos = find(path.begin(),path.end(),i);
if(pos == path.end())
{
path.push_back(i);
dps_permute(nums,path,result);
path.pop_back();
}
}
}