第一步:我们首先遍历大小为n的数组,找到最大值和最小值max,min。
第二步:用n+1个桶来处理数据,将最小的数放在第一个桶,最大的数放在第n+1个桶中,由于数组大小为n,所以必然有一个桶是空桶,所以最大间隔值必然出现在两个桶之间,可用数学上的反证法证明。
咱们用三个不同的数组来记录每个桶的状态,
boolean[] hasNum = new boolean[len+1]; 桶中是否有数据
int[] maxs = new int[len+1]; 桶中的最大值
int[] mins = new int[len+1]; 桶中的最小值
package test;
/**
* @author your_tt
* @date 2021年05月25日19:07
*/
public class maxGap{
public static int findMax(int[] array){
if(array == null|| array.length<2){
return 0;
}
int len=array.length;
int max=Integer.MIN_VALUE;
int min=Integer.MAX_VALUE;
for(int i = 0;i<array.length;i++){
max=Math.max(max,array[i]);
min=Math.min(min,array[i]);
}
if (max == min){
return 0;
}
boolean[] hasNum = new boolean[len+1];
int[] maxs = new int[len+1];
int[] mins = new int[len+1];
for (int i = 0;i<array.length;i++){
int bit = bucket(array[i],min,max,len);
maxs[bit] = hasNum[bit] ? Math.max(maxs[bit],array[i]) : array[i];
mins[bit] = hasNum[bit] ? Math.min(mins[bit],array[i]) : array[i];
hasNum[bit] = true;
}
int gap=0;
int lastNUm=maxs[0];
for(int j=1;j<len+1;j++) {
if (hasNum[j]) {
gap = Math.max(gap, mins[j] - lastNUm);
lastNUm=maxs[j];
}
}
return gap;
}
//给定一个数,判断这个数来自哪个桶
public static int bucket(int num,int min,int max,int len){
return (int)((num-min)*len)/(max-min);
}
public static void main(String[] args) {
int[] arr = {4,3,7,87,45};
System.out.println(findMax(arr));
}
}