题目描述
给定一个长度为N 的数组A = [A1, A2,…,AN],数组中有可能有重复出现的整数。
现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改A2,A3,…, AN。当修改Ai 时,小明会检查Ai 是否在A1~ Ai-1 中出现过。如果出现过,则小明会给Ai 加上1 ;如果新的Ai 仍在之前出现过,小明会持续给Ai 加1 ,直到Ai 没有在A1~Ai-1中出现过。当AN 也经过上述修改之后,显然A数组中就没有重复的整数了。
现在给定初始的A 数组,请你计算出最终的A 数组。
输入
第一行包含一个整数N(1<=N<=100000)
第二行包含N个整数A1,A2,…,AN(1<=Ai<=1000000)
输出
输出N个整数,依次是最终的A1,A2,…,AN
样例输入
5
2 1 1 3 4
样例输出
2 1 3 4 5
题解
next [ ] 数组存储该数字下一个该存放的位置。如果有冲突,那么就把该数字变为next[ ] 中的数字,然后更新该位置的信息即可。只有当next[i]=i 的时候。该位置才“空闲”,才可以存放,否则原来的位置有数字了,就要把新的数字往后挪到 next[i] 指示的位置,而不是,一个一个挪,再判断。
#include<bits/stdc++.h>
using namespace std;
int ans[200000];
int nnext[1000000];
int find(int i) {
return nnext[i] == i ? i : nnext[i] = find(nnext[i]);
}
int main() {
for (int i = 0; i < 1000000; i++)
nnext[i] = i;
int n, a;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a);
ans[i] = find(a);
nnext[ans[i]] = ans[i] + 1; //更新next[]
}
for (int i = 0; i < n; i++) {
printf("%d ", ans[i]);
}
return 0;
}