目录
前言
Perm算法是一种解决全排列问题的思想,它是递归的一个实例。
一、递归算法
一个直接或间接地调用自身的算法成为递归算法。递归算法有两个基本组成元素:递归方程(一个使用函数自身给出定义的函数)和边界条件。
在合并排序和快速排序一问中,我总结了分治策略在大规模问题中的引用。递归算法与分治策略都是将分体划分后重复调用并求解的过程,区别在于递归算法是已知问题的结果和边界条件;分治法是已知问题的中间过程,再逐步将问题划分并求解。
二、Perm算法
1.全排列问题
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
全排列数:
使用Perm算法解决全排列问题的代码如下:
template <class Type>
void Perm(Type list[],int k,int m){
if(k==m){
for(int i=0;i<=m;i++)
cout<<list[i];
cout<<endl;
}
else
for(int i=k;i<=m;i++){
Swap(list[k],list[i]);
Perm(list,k+1,m);
Swap(list[k],list[i]);
}
}
template <class Type>
inline void Swap(Type &a,Type &b){
Type temp=a;
a=b;
b=temp;
}
在排列一个长度为n的数组时,依次让每个元素成为数组的“头部”,对其他n-1个元素进行全排列,待排元素数为1时,直接输出结果。为了方便,设置参数k、m,令它们分别指向待排数组首尾,通过增减k、m移动指针。需要注意的是,每一次完成交换list[p]和list[i]的排序后,都需要把它们再次交换到原位后再进行下一次排列。
Perm算法时间复杂度为,在实际问题中,根据条件的不同全排列问题还有许多优化解法。
2.全排列问题的其他解法
(1)Johnson-Trotter算法
Johnson-Trotter算法并未提高代码运行的时间复杂度,但是它不需要将多余的遍历信息压栈,降低了空间复杂度。
(2)回溯算法解决全排列
leetcode相关例题的讲解非常清楚,附上链接以便后续学习。
总结
以上就是关于Perm算法解决全排列的所有内容。