题目链接:精选项目课程_IT热门课程_蓝桥云课课程 - 蓝桥云课
题目解析:
①可以使用桶算法,用vis数组标记一个数是否被使用,时间复杂度最坏为o(n^2),能得80%的分数
②使用并查集,每次将原来的数a[i]替换为find(a[i]);每次使用一个数(即find(a[i])),将其并入该数+1的集合中,复杂度o(nlog(n))
代码(②):
//#define local
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
int n;
int s[100005],a[100005];
int find(int x){
if(x!=s[x])
s[x]=find(s[x]);
return s[x];
}
int main(){
#ifdef local
freopen("data.in","rb",stdin);
//freopen("data.out","wb",stdout);
#endif
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
s[i]=i;
}
for(int i=1;i<=n;i++){
a[i]=find(a[i]);
s[a[i]]=find(a[i]+1);
}
for(int i=1;i<=n;i++){
printf("%d",a[i]);
if(i!=n)
printf(" ");
}
return 0;
}