簡單的辦法是排序,然後很容易就計算到了最大的間距,可是排序最快的時間複雜度是O(NlogN),不符合題目要求。
換一個思路,就是空間換時間,這裏也沒有對空間有要求。這裏實現的算法就是多費了點內存,最後時間複雜度O(N),滿足了要求。具體算法看以下代碼。
package test;
import java.util.Arrays;
/**
* 一串數,求相鄰的兩個數的最大間距。如[1.3,3.1,2,5,5.4,6.1],最大間距是1.9
* @date 2014-4-14
* @encode UTF-8
* */
public class MaxGap {
/**
* 計算一組數x中相鄰數的最大間距
* </br>
* 算法:首先找到最大、最小數,則x所有數在這兩個數構成的區間內。
* 將這個區間均分成n份(n是個數),則x中任意一個數在某區間內。
* 一個小區間內可能不含x的數,也可能包含多個,只記錄該區間內的最大數、最小數。
* 再遍歷各區間,兩個都有數的區間之間的最大間距,也就是要求的最大間距。
* @warn x的長度>=2
* @param x 若干數
* */
public double maxGap(double[]x){
double min,max,avrGap;
//y[2*j]是區間j最小數的下標,y[2*j+1]是最大數的下標
int[]y=new int[2*x.length];
Arrays.fill(y, -1);
min=max=x[0];
//計算最大數、最小數
for(double xt:x)
if(xt>max)
max=xt;
else if (xt<min)
min=xt;
//小區間的長度
avrGap=(max-min)/(x.length-1);
for(int j=0;j<x.length;j++){
//數x[j]所在的區間
int index=(int)((x[j]-min)/avrGap);
//計算這個區間裏包含的最大數、最小數
if(y[2*index]==-1){
y[2*index]=y[2*index+1]=j;
}else if(x[y[index*2]]>x[j])
y[2*index]=j;
else if(x[y[2*index+1]]<x[j])
y[2*index+1]=j;
}
double lastMax=min,maxGap=avrGap;
//遍歷所有區間
for(int j=0;j<x.length;j++){
//若該區間至少包含一個數,
//則計算上一個有數的區間的最大數與該區間最小數的差
if(y[2*j]>=0){
if(x[y[2*j]]-lastMax>maxGap)
maxGap=x[y[2*j]]-lastMax;
lastMax=x[y[2*j+1]];
//該區間無數,跳過
}else{
continue;
}
}
return maxGap;
}
}