題目描述
給定一個長度爲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;
}