問題描述
輸入整數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;
}