全排列问题
给定一个一个序列,输出他的全排列
比如{1,2,3}.
全排列就是:
1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1
可以先看一个例子。
给定一个序列输出下一个比它大的序列
例如:arr{1,2,3,5,4}
比它大的下一个排列就是{1,2,4,3,5}
具体怎么做的?
1.从arr.len-1位置到0开始找arr[i]>arr[i-1].找到之后,将i-1位置的数记住ind1;没找到则说明这个序列没有下一个比它大的序列。
2.从arr.len-1位置到i-1位置开始找arr[i]>ind1的数。讲这个数记做ind2。
3.将ind1和ind2交换。
4.将i位置和arr.len-1位置的元素排序或者逆序。
例子演示:
1.先找到ind1就是3,它的下标是2,i下标就是3.
2.在找到ind2就是4。
3.将ind1和ind2交换。
4.将3位置和arr.len-1位置的元素排序或者逆序。
比它大的下一个排列就是{1,2,4,3,5}。
下一个更大排列代码:
bool nextPermutation(vector<int>& nums)
{
int i=nums.size()-1;
for(;i>=1;i--)
{
if(nums[i]>nums[i-1])
{
int j=nums.size()-1;
for(;j>=i;j--)
{
if(nums[j]>nums[i-1])
break;
}
swap(nums[i-1],nums[j]);
sort((nums.begin()+i),nums.end());
return true;
}
}
if(i==0)
return false;
}
其实C++的头文件中有一个方法就是我们上面实现的这个,叫做next_permutation(begin(),end()),它的返回值为bool类型,true表示找到,false表示找不到!
接下来再看全排列问题就容易多了,其实就是将序列sort为最小,然后求出它的所有下一个更大的排列。
库函数实现全排列:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int> v{ 1,2,3 };
sort(v.begin(),v.end());
do
{
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
cout << endl;
} while (next_permutation(v.begin(), v.end()));
return 0;
}
应用咱们自己写的方法实现全排列:
class Solution {
bool nextPermutation(vector<int>& nums)
{
int i=nums.size()-1;
for(;i>=1;i--)
{
if(nums[i]>nums[i-1])
{
int j=nums.size()-1;
for(;j>=i;j--)
{
if(nums[j]>nums[i-1])
break;
}
swap(nums[i-1],nums[j]);
sort((nums.begin()+i),nums.end());
return true;
}
}
return false;
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums)
{
sort(nums.begin(),nums.end());
vector<vector<int>> ret;
do
{
ret.push_back(nums);
}while(nextPermutation(nums));
return ret;
}
};
结果:
PS:这个方法同样适用于求含有重复数的全排列哦!