相鄰數的最大間距

一串數,求相鄰的兩個數的最大間距。如[1.3,3.1,2,5,5.4,6.1],最大間距是1.9,就是3.1、5的間距。時間複雜度要求O(N)。
簡單的辦法是排序,然後很容易就計算到了最大的間距,可是排序最快的時間複雜度是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;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章