给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
示例:
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。说明:
你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。
class Bucket { int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; } public class 题164桶排序 { public int maximumGap(int[] nums) { if (nums == null || nums.length < 2) { return 0; } int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int i : nums) { min = Math.min(min, i); max = Math.max(max, i); } if(max == min) { return 0; } // 桶长度 = 区间总长度 / 区间总个数 int bucketSize = Math.max(1, (max - min) / (nums.length - 1)); // 桶个数 = 区间长度 / 桶长度。 由于开闭区间的问题,多加一个桶 Bucket[] buckets = new Bucket[(max - min) / bucketSize + 1]; for (int i = 0; i < nums.length; ++i) { //定位到桶的时候,一般是 (当前元素 - 最小值) / 桶长度, 这里利用了整数除不尽向下取整的性质 int loc = (nums[i] - min) / bucketSize; if (buckets[loc] == null) { buckets[loc] = new Bucket(); } //桶只记录放入桶中元素的最大值,最小值。每放一个则更新最大值最小值 buckets[loc].min = Math.min(buckets[loc].min, nums[i]); buckets[loc].max = Math.max(buckets[loc].max, nums[i]); } int previousMax = Integer.MAX_VALUE; //记录上一个桶的最大值 int maxGap = Integer.MIN_VALUE; for (int i = 0; i < buckets.length; ++i) { if (buckets[i] != null && previousMax != Integer.MAX_VALUE) { maxGap = Math.max(maxGap, buckets[i].min - previousMax); //桶间间距比较 } if (buckets[i] != null) { previousMax = buckets[i].max; maxGap = Math.max(maxGap, buckets[i].max - buckets[i].min); //桶内间距比较 } } return maxGap; } }