Maximum Gap
题目大意:
给定一个未排序的数组,找出其排序后的序列中两个相邻元素之间的最大差值。最好在线性时间、线性空间复杂度内完成。如果数组少于2个元素,返回0。可以假设数组中的所有元素均为非负整数,并且在32位带符号整数的范围以内。
解题思路:
基数排序(radix sort)/桶排序(bucket sort)
官方版(桶排序):
假设有N个元素A到B。
那么最大差值不会小于 (B - A) / N + 1,即最大差值大于等于len。
令bucket(桶)的大小 gap = (B - A) / N + 1,则最多会有 N 个桶
对于数组中的任意整数K,很容易通过算式index = (K - A) / gap找出其桶的位置,然后维护每一个桶的最大值和最小值
由于同一个桶内的元素之间的差值至多为len - 1(因为最大差值大于等于len),因此最终答案不会从同一个桶中选择。
对于每一个非空的桶p,找出下一个非空的桶q,则q.min - p.max可能就是备选答案。返回所有这些可能值中的最大值。
public class Solution {
public int maximumGap(int[] num) {
if (num == null || num.length < 2) return 0;
int min = num[0];
int max = num[0];
for (int i : num) {
min = Math.min(min, i);
max = Math.max(max, i);
}
int gap = (max - min) / num.length + 1;
int[] bucketsMin = new int[num.length];
int[] bucketsMax = new int[num.length];
Arrays.fill(bucketsMin, Integer.MAX_VALUE);
Arrays.fill(bucketsMax, Integer.MIN_VALUE);
for (int i = 0; i < num.length; i++) {
if (num[i] == max || num[i] == min) continue;
int index = (num[i] - min) / gap;
bucketsMin[index] = Math.min(bucketsMin[index], num[i]);
bucketsMax[index] = Math.max(bucketsMax[index], num[i]);
}
int ans = Integer.MIN_VALUE;
int previous = min;
for (int i = 0; i < num.length; i++) {
if (bucketsMin[i] == Integer.MAX_VALUE || bucketsMax[i] == Integer.MIN_VALUE)
continue;
ans = Math.max(ans, bucketsMin[i] - previous);
previous = bucketsMax[i];
}
ans = Math.max(ans, max - previous);
return ans;
}
}

浙公网安备 33010602011771号