问题描述
输入整数n,随后输入n个整数,求整数的最大间隙,要求线性时间复杂度。
思路描述
易知若输入n个整数,则其最大间隙一定大于等于w=(Max-Min)/(n-1),其中Max与Min分别为输入的n个数字的最大值与最小值。
故可以w为区间长度,将数字取值分为n-1个区间,分别记录每个区间各自的最值(最大值及最小值),再将其作差进行比较。
源代码
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int o[n]={0};
cin>>o[0];
int max,min;
max=o[0];
min=o[0];
for(int a=1;a<n;a++)
{
cin>>o[a];
max=max>o[a]?max:o[a];
min=min>o[a]?o[a]:min;
}//输入,得到最大值与最小值
int w=(max-min)/(n-1);//区间宽度
int p[(n-1)*2+2]={0};//记录各区间最值
int q[(n-1)*2+2]={0};//标记各区间最值是否被记录
for(int a=0;a<n;a++)
{
int b=(o[a]-min)/w*2;
if(!q[b])
{
q[b]=1;
p[b]=o[a];
}//若区间最小值未被记录,则记录
else
{
int c=p[b];
p[b]=o[a]>p[b]?p[b]:o[a];
o[a]=o[a]>c?o[a]:c;
if(!q[b+1])
p[b+1]=o[a];
else
p[b+1]=o[a]>p[b+1]?o[a]:p[b+1];
q[b+1]=1;
}//若区间最小值已被记录,则检测区间最大值是否被记录:
//若未被记录,则将区间最小值与当前值比较,小者记录为区间最小值,大者记录为区间最大值
//若已被记录,则将三者比较,最小者记录为区间最小值,最大者记录为区间最大值
}
int l=0;
for(int a=0;p[a]!=max;)
{
while(!q[a])
a++;
int b=a+1;
while(!q[b])
b++;
int c=p[b]-p[a];
l=l>c?l:c;
a=b;
}//将相邻的记录值作差,纪录最大值
cout<<l;//输出最大间隙
return 0;
}