题目:输入N个数,求这N个数排序后,相邻数的最大差值。要求时间复杂度为O(n).
我们可以用桶排序的思想, 把N个数分到 N + 1个桶中,然后我们用桶存连续长度的一个范围的数,每个桶负责的范围是(maxn - minn)/ N(maxn是序列中最大的数,minn是序列中最小的数), 如果一个数为num,那么这个数应存进(num - minn) * N / (maxn - minn) 号桶。
由相邻数差值的平均值为(maxn - minn) / ( N - 1) 和每个桶负责的范围可轻易得知相邻最大差肯定不在同一个桶内, 排序后的最大差值只可能来自某个非空桶中的最小值减去前一个非空桶中的最大值,所以每个桶只记录最大值和最小值就行了。
#include<iostream>
using namespace std;
const ll inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e5 + 10;
int n;
int a[N];
int vis[N];//判断该桶有没有数
int maxs[N], mins[N];
int main()
{
cin >> n;
int maxn = 0, minn = inf;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
maxn = max(maxn, a[i]);
minn = min(minn, a[i]);
}
if (maxn == minn)//特判
cout << 0 << endl;
else
{
for (int i = 1; i <= n; i++)
{
int num = (a[i] - minn) * (ll)n / (maxn - minn);
maxs[num] = vis[num] ? max(a[i], maxs[num]) : a[i];
mins[num] = vis[num] ? min(a[i], mins[num]) : a[i];
vis[num] = 1;
}
int last = maxs[0];
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (vis[i])
{
ans = max(ans, mins[i] - last);
last = maxs[i];
}
}
cout << ans << endl;
}
return 0;
}