求排列:swap交换法
swap交换法
核心:
分治+回溯
-
dfs(s,t)表示:本轮要放的位置是s,待排列的区间是[s,t] -
对于当前位置
s,尝试将[s,t]内的每个元素放到s一次 -
swap(a[s],a[i]):(1)
a[s]->a[i]将a[s]这个数扔到待排序部分(2)
a[s]<-a[i]将a[i]这个数放到位置s上 -
dfs(s+1,t):放第s+1个位置 -
swap(a[s],a[i]):回溯 -
同一层
dfs(s,t):遍历每一种可能——尝试在位置s放不同的数
模版:
void dfs(int s,int t)//正在把[s,t]内的数放在第s位
{
if(s==t){//若[s,t]只有一个数 放完了
for(int i=startIndx;i<=t;++i)
cout<<a[i];
cout<<"\n";
}
for(int i=s;i<=t;++i){ //在当前位置s尝试放不同的数
swap(a[s],a[i]); //把a[i]放在第s位
dfs(s+1,t); //继续放第s+1位
swap(a[s],a[i]); //(回溯)换回来
}
}
例子:
假设数组是[1,2,3],要得到这三个数的全排列
dfs(0,2):当前要放第0个位置的数
|---i=0: swap(a[0],a[0]) -> [1,2,3] 第0个位置放a[0]
| dfs(1,2):当前要放第1个位置的数
| |--i=1: swap(a[1],a[1]) -> [1,2,3] 第1个位置放a[1]
| | dfs(2,2): cout<<[1,2,3]
| | swap(a[1],a[1]) -> [1,2,3] 换回来(回溯)
| |--i=2: swap(a[1],a[2]) -> [1,3,2] 第1个位置放a[2]
| | dfs(2,2): cout<<[1,3,2]
| | swap(a[1],a[2]) -> [1,2,3] 换回来(回溯)
| swap(a[0],a[0]) -> [1,2,3]
|
|---i=1: swap(a[0],a[1]) -> [2,1,3] 第0个位置放a[1]
| dfs(1,2):当前要放第1个位置的数
| |--i=1: swap(a[1],a[1]) -> [2,1,3]
| | dfs(2,2): cout<<[2,1,3]
| | swap(a[1],a[1]) -> [2,1,3]
| |--i=2: swap(a[1],a[2]) -> [2,3,1]
| | dfs(2,2): cout<<[2,3,1]
| | swap(a[1],a[2]) -> [2,1,3]
| swap(a[0],a[1]) -> [1,2,3]
|
|---i=2: swap(a[0],a[2]) -> [3,2,1] 第0个位置放a[2]
dfs(1,2):当前要放第1个位置的数
|--i=1: swap(a[1],a[1]) -> [3,2,1]
| dfs(2,2): cout<<[3,2,1]
| swap(a[1],a[1]) -> [3,2,1]
|--i=2: swap(a[1],a[2]) -> [3,1,2]
| dfs(2,2): cout<<[3,1,2]
| swap(a[1],a[2]) -> [3,2,1]
swap(a[0],a[2]) -> [1,2,3]
变式:
求数组某段区间的全排列,类似于求\((A^k_n)\)
int a[]={1,7,3,2};
int startIndx,endIndx;
void dfs(int s,int t)//正在放位置为s的数
{
if(s==t){//若[s,t]只有一个数 a[s]原地不动
for(int i=startIndx;i<=t;++i)
cout<<a[i];
cout<<"\n";
}
for(int i=s;i<=t;++i){
swap(a[s],a[i]);//位置s放数a[i]
dfs(s+1,t);//放位置s+1
swap(a[s],a[i]);//换回来
}
}
int main()
{
startIndx=1,endIndx=3;
dfs(startIndx,endIndx);
return 0;
}
练习:
修改上述代码,写出从{1,2,3,4,5,6}选3个数的代码,观察输出,看看具体怎么放数的?
int a[]={1,2,3,4,5,6};
void getA(int s,int t)
{
if(s==3){//6选3 全排列
for(int i=0;i<=2;++i){
cout<<a[i];
}
cout<<"\n";
return ;
}
for(int i=s;i<=t;++i){
swap(a[s],a[i]);
getA(s+1,t);
swap(a[s],a[i]);
}
}
int main()
{
getA(0,5);
return 0;
}


浙公网安备 33010602011771号