题目链接:点击这里
vis数组标记判重,通过80%
数组元素全部相同时,时间复杂度为 ,超时:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100010];
bool vis[1000010];
int main()
{
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
vis[a[1]] = true;
for(int i = 2; i <= n; ++i)
{
while(vis[a[i]])
{
a[i]++;
}
vis[a[i]] = true;
}
for(int i = 1; i <= n; ++i)
printf("%d ", a[i]);
return 0;
}
搜题解:
这题可以巧妙地利用并查集。 我们初始化 的父亲为 ,然后依次遍历输入的数组,使 ,再令 即可。
假如数组为 。
-
第一次输入 ,,更新
-
第二次输入 ,,更新
-
第三次再输入 ,, 这时候 便等于 了。
这种查询的时间复杂度仅为 。整体时间复杂度 。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int a[maxn], f[maxn];
int find(int x)
{
if(f[x]==x) return x;
else return f[x] = find(f[x]);
}
int main()
{
for(int i = 1; i <= maxn; i++) //初始化f数组为它本身
f[i] = i;
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
a[i] = find(a[i]); //直接把这个数变成他的父亲
f[a[i]] = find(a[i]+1);
}
for(int i = 1; i <= n; ++i)
printf("%d ", a[i]);
return 0;
}
来源:CSDN
作者:菜是原罪QAQ
链接:https://blog.csdn.net/qq_42815188/article/details/104447799