返回目录
题意
给出0,1…,N-1的一个序列,要求通过两两交换的方式变成递增序列,每次只能用0和其他数字交换,求最小的交换次数
样例(可复制)
10
3 5 7 2 6 4 9 0 8 1
样例输出
9
提供几个易错样例
5
0 1 2 3 4
//output 0
5
1 2 3 4 0
//output 4
9
0 2 1 4 3 6 5 8 7
//output 12
注意点
- 本题简单的蛮力算法很好想,但容易超时,本题使用了pos用来存放每个数字的位置和k存放当前最小的不在本位上的数,使得算法过程中,不需要再查找交换的数,算法的时间复杂度变为了线性
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,tmp,ok=0,k=1,swap=0;
int pos[100010];
cin>>n;
for(int i=0;i<n;i++){
scanf("%d",&tmp);
pos[tmp]=i;
if(tmp==i)ok++;
}
while(ok!=n){
if(pos[0]!=0){
tmp=pos[pos[0]];
pos[pos[0]]=pos[0];
pos[0]=tmp;
ok++;
if(pos[0]==0)ok++;
}else{
while(k<n){
if(pos[k]!=k){
tmp=pos[k];
pos[k]=pos[0];
pos[0]=tmp;
ok--;
break;
}
k++;
}
}
swap++;
}
cout<<swap;
return 0;
}