问题描述:
给定一个无序数组arr,返回如果排序之后,相邻数之间的最大差值。{3,1,7,9},如果排序后{1,3,7,9},相邻数之间的最大差值来自3和7,返回4。
要求:不能真的进行排序,并且要求在时间复杂度O(N)内解决。
思想:
准备数组长度加一的桶,桶中值存储这个桶的最大值、最小值还有是否为空桶。数组中的最小值一定在第一个桶中,最大值一定也在最后一个桶中。那么这些桶中必然有一个为空桶,计算空桶后面的桶的最小值减去空桶前面的最大值的结果记为a,a不一定为最终的答案(这是因为相邻两个桶之前后桶最小值减去前桶最大值可能大于a),但是小于a的值一定不是最终答案,用于排除不正确的答案。
代码:
public static int maxGap(int[] nums) {
if (nums == null || nums.length < 2) {
return 0;
}
int len = nums.length;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < len; i++) {
min = Math.min(min, nums[i]);
max = Math.max(max, nums[i]);
}
if (min == max) {
return 0;
}
//len个数据,准备len+1个桶
boolean[] hasNum = new boolean[len + 1];
int[] maxs = new int[len + 1];
int[] mins = new int[len + 1];
int bid = 0;//桶号
for (int i = 0; i < len; i++) {
bid = bucket(nums[i], len, min, max);
mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i];
maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i];
hasNum[bid] = true;
}
int res = 0;
int lastMax = maxs[0];//上一个非空桶的最大值
int i = 1;
for (; i <= len; i++) {
if (hasNum[i]) {
res = Math.max(res, mins[i] - lastMax);
lastMax = maxs[i];
}
}
return res;
}
public static int bucket(long num, long len, long min, long max) {
return (int) ((num - min) * len / (max - min));
}
public static int comparator(int[] nums){
if (nums==null||nums.length<2){
return 0;
}
Arrays.sort(nums);
int res = 0;
for (int i=1;i<nums.length;i++){
res = Math.max(res,nums[i]-nums[i-1]);
}
return res;
}
public static int[] genreateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) (Math.random() * maxSize)];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * maxValue);
}
return arr;
}
public static void printArray(int[] arr){
if (arr==null||arr.length==0){
return;
}
for (int i =0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int maxSize = 20;
int maxValue = 20;
int testTime = 100;
System.out.println("test begin!");
for (int i =0;i<testTime;i++){
int[] arr = genreateRandomArray(maxSize,maxValue);
int res1 = maxGap(arr);
int res2 = comparator(arr);
if (res1!=res2){
System.out.println("Oops!");
printArray(arr);
System.out.println("res1: "+res1);
System.out.println("res2: "+res2);
break;
}
}
System.out.println("test end!");
}