输入样例
5
2 1 1 3 4
输出样例
2 1 3 4 5
运行限制
最大运行时间:1s
最大运行内存: 256M
算法
(并查集)
朴素思路:利用哈希表,类似于bool数组,如果出现,就进行+1得到一个,如果发生矛盾就需要遍历整个数组,最坏情况复杂度为O(n^2),不能实现题目要求的大数据。
优化算法:利用并查集,这样时间复杂度就来到了O(1)。
首先,初始化
find(x)表示找到x的祖宗
father(fa)数组:所有的元素都指向自身(一开始都是fa[i]指向i),也就说明都没访问过
因为有时候有些数据会重复,当我们再次访问到i的时候(重复访问i),这时候我们需要按照题目要求访问i+1,因此当我们访问了i以后,就需要更新fa[i]=fa[i+1],这样当再次访问i时我们1qi其实是访问了i+1,并输出fa[i+1]
但又有另一个问题,当按照上面的步骤访问i+1时,i+1可能在之前也访问过了,所以说我们就把更新改为fa[i]=find(i+1)
这里比较难理解,就是说为什么要更新为find(i+1),为什么要找i+1的祖宗在付给fa[i],
因为我们前面说了当一个之前没有被访问的数被访问之后会将fa[i]更新为fa[i+1],
而如果一个数之前被访问,那么就把这个数更新(+1),再看这个数有没有被访问过,
因此find(i+1)其实是从i+1往后第一个没有被访问的数。
Python3 代码
import os
import sys
N=1000010
n=int(input())
alist=[int(x) for x in input().split()]
fa=[x for x in range(N)]
def find(x):
if fa[x]!=x:
fa[x]=find(fa[x])
return fa[x]
for i in range(n):
//这里比较难理解,可以在草稿上把样例多推几遍
alist[i]=find(alist[i])
fa[alist[i]]=find(alist[i]+1)
for i in range(n):
print(alist[i],end=' ')