全排列可以用分治的思想去实现,主要操作步骤是将首个元素与剩余其他的所有元素进行交换。主要分为两种:允许生成不重复的序列和不允许生成重复的序列。
1.允许重复的序列,代码如下:
class Solution { public: void fullArray(int a[] ,int len) { arrayCore(a,0,len); } void arrayCore(int a[],int index,int len) { if(index == len - 1) { Print(a,len); return; } for(int i = index; i < len; i++) { swap(a[index],a[i]); arrayCore(a,index + 1,len); swap(a[index],a[i]);//在进行以下个元素为首元素的交换前,先恢复原序列的位置 } } void Print(int a[],int len) { for(int i= 0; i < len; i++) cout<<a[i]<<" "; cout<<endl; } };
2.不允许重复的序列:
class Solution { public: void fullArray(int a[] ,int len) { arrayCore(a,0,len); } void arrayCore(int a[],int index,int len) { if(index == len - 1) { Print(a,len); return; } for(int i = index; i < len; i++) { if(!isSwap(a,index,i)) continue; else { swap(a[index],a[i]); arrayCore(a,index + 1,len); swap(a[index],a[i]); } } } void Print(int a[],int len) { for(int i= 0; i < len; i++) cout<<a[i]<<" "; cout<<endl; } bool isSwap(int a[],int _start,int _end) { for(int i = _start; i < _end; i++) { if(a[i] == a[_end]) return false; } return true; } };
在非重复的情况下,需要判断一下:index之后的元素中是否有存在与之前a[i]重复的元素,如果有重复的话,就跳过这个循环,直接进行下一个循环。
3.有时题目会要求按照字典顺序打印出所有的排列,此时只需在打印前对结果进行排序即可。例如本例中,就不能直接调用Print函数了,应该是把所有的排列存到一个数组或者vector中,再对这个数组或vector进行排序,之后再打印即可。
主要有以下几点需要注意:
(1)交换的那个for循环时候是从index开始的,而不是从index+1开始的,交换index相当于输出它本身的那个序列;如果从index+1开始的话,就会漏掉以index开头的序列。
(2)程序的开始只需把0位置传入即可。
参考:http://blog.csdn.net/lemon_tree12138/article/details/50986990