题目 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序。
思路 应用桶排序,但是要基于排序来操作。步骤如下:
(1)遍历数组,找出数组的最大值max和最小值min,若max==min则说明数组中数字相同,返回0;
(2)以min和max为区间端点,均等划分arr.length+1个桶(可以理解为区间);
(3)遍历数组,若当前数字属于第i个桶,则更新并记录第i个桶的当前最大值、最小值,并标记此桶已经有过数值。
(4)相邻数的最大差值必然存在于不同的桶之间。因为有arr.length个数值,而有arr.lrngth+1个桶,所以必然存在空桶。桶内数值之间的差值必然小于隔一个空桶的差值。所以,相邻数的最大差值必然存在于不同的桶之间,即前一个非空桶的最大值与后一个非空桶的最小值之差。
package algorithm.section2;
import java.util.Arrays;
public class MaxGap {
public static int maxGap(int[] arr){
if (arr == null || arr.length < 2) return 0;
int[] maxs = new int[arr.length + 1];
int[] mins = new int[arr.length + 1];
boolean[] hasNum = new boolean[arr.length + 1];
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++){
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
if (max == min) return 0;
// double gap = (double) ((max - min) / arr.length);
for (int i = 0; i < arr.length; i++){
int index = (int) ((arr[i] - min) * arr.length / (max - min));
maxs[index] = hasNum[index] ? Math.max(maxs[index], arr[i]) : arr[i];
mins[index] = hasNum[index] ? Math.min(mins[index], arr[i]) : arr[i];
hasNum[index] = true;
}
int res = 0;
int lastMax = maxs[0];
for (int i = 1; i <= arr.length; i++){
if (hasNum[i]) {
res = Math.max(res, mins[i] - lastMax);
lastMax = maxs[i];
}
}
return res;
}
// for test
public static int comparator(int[] nums) {
if (nums == null || nums.length < 2) {
return 0;
}
Arrays.sort(nums);
int gap = Integer.MIN_VALUE;
for (int i = 1; i < nums.length; i++) {
gap = Math.max(nums[i] - nums[i - 1], gap);
}
return gap;
}
// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 10;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
int[] arr2 = copyArray(arr1);
if (maxGap(arr1) != comparator(arr2)) {
succeed = false;
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
}
}