题目
给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序。
思路
-
采用桶排序思路,如果数组中有N个数,则创建N+1个桶,将数据均匀分布到桶中,则一定存在1个空桶,保证最大差值一定不是出现在同一个桶中;
-
记录所有桶中的最大值和最小值以及是否为空;
-
遍历所有桶,比较 【非空桶】 的最小值,与前一个【 非空桶的最大值】,求 最大的差值;
代码实现
private 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;
//先遍历数组找到最小值和最大值,并赋值给min和max
for (int i = 0; i < nums.length; i++) {
min = Math.min(min, nums[i]);
max = Math.max(max, nums[i]);
}
if (min == max) {
//最小值和最大值相等,则直接返回0
return 0;
}
//将nums数组中的数均分到len+1个桶中,则必有一个空桶【因为长度多1个】,构造三个数组maxs、mins、hasNum分别表示每个桶中最大值、最小值以及当前桶是否有元素
int[] maxs = new int[len + 1];
int[] mins = new int[len + 1];
boolean[] hasNum = new boolean[len + 1];
//记录nums数组中每个数存放的桶号
int bucketNo = 0;
for (int i = 0; i < len; i++) {
//根据最大值、最小值以及数组长度,计算i位置元素应该放在几号桶中
bucketNo = bucket(nums[i], len, min, max);
//比较i位置元素与对应桶中最大元素比,如果比最大元素大,则替换
maxs[bucketNo] = hasNum[bucketNo] ? Math.max(maxs[bucketNo], nums[i]) : nums[i];
//比较i位置元素与对应桶中最小元素比,如果比最小元素小,则替换
mins[bucketNo] = hasNum[bucketNo] ? Math.min(mins[bucketNo], nums[i]) : nums[i];
hasNum[bucketNo] = true;
}
int result = 0;
int resultMax = maxs[0];
//依次遍历所有桶,比较 【非空桶】 的最小值,与前一个【 非空桶的最大值】,求 最大的差值;
for (int i = 1; i < len + 1; i++) {
if (hasNum[i]) {
result = Math.max(result, mins[i] - resultMax);
resultMax = maxs[i];
}
}
return result;
}
/**
* 计算当前数num应该被放入哪个桶中
*
* @param num 数组中的元素
* @param len 数组的长度
* @param min 数组最小值
* @param max 数组最大值
* @return 对应的桶号
*/
private static int bucket(int num, int len, int min, int max) {
return (num - min) * len / (max - min);
}
结语
如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )