定义
从n个元素中取出n个元素进行排列,即为全排列。则共有n!
种排列方式。
所以全排列问题的时间复杂度为O(n*n!)
递归法
执行过程:
- 首先枚举全排列第一个位置的数
- 然后递归枚举后面位置上的数,直到最后一位
- 递归到最后一位时,即找到了一个排列,输出
- 每执行一次,需将数组还原一次
代码:
void fun(int a[],int l,int r)//a[]为储存元素的数组,l为第一个元素位置,r为最后一个元素位置
{
if(l==r)//枚举前缀到数组最后一位数,即已经找到一个排列
{
cout<<a[1];
for(int i=2;i<=r;i++)//输出排列
{
cout<<" "<<a[i];
}
cout<<endl;
}
else
{
for(int i=l;i<=r;i++)//枚举前缀
{
swap(a[i],a[l]);//交换前缀的值
fun(a,l+1,r);//确定下一位的前缀
swap(a[i],a[l]);//为避免重复,需还原数组
}
}
}
STL中的全排列
头文件:#include <algorithm>
函数模板:next_permutation(arr, arr+size);
当有下一个较大值返回1,否则返回0。
函数模板:prev_permutation(arr, arr+size);
当有上一个较小值返回1,否则返回0
其中:
- arr为数组
- size为数组长度。
例如:
3 2 1,只有上一个较小值,没有下一个较大值。1 2 3只有下一个较大值,没有上一个较小值。2 1 3 的上一个较小值为 1 3 2,下一个较大值为 2 3 1。(涉及到字典序的概念)
所以使用函数模板前,需对序列进行排序。
代码实现:
do{
for(int i=0;i<size;i++)
cout<<arr[i]<<endl;
}while(next_permutation(arr, arr+size))