全排列可以用分治的思想去实现,主要操作步骤是将首个元素与剩余其他的所有元素进行交换。主要分为两种:允许生成不重复的序列和不允许生成重复的序列。
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