题目
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
Try to solve it in linear time/space.
Return 0 if the array contains less than 2 elements.
You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
# 思路 本题给定一个无序数组,要你求有序情况下相邻数值的最大差值。如果没有时间复杂度,那么先排序再求差值是显而易见的方案。但是题目要求必须线性时间与空间。因此我们必须思考出能够解决这个问题的好方法。这道题目我们我们可以推导出一个准确的结论:假如数组的最大值为max,最小值为min,数组大小为N,那么最大的差值gap一定不小于平均gap: $ceil((max-min)/N-1)$ 假如我们按照gap来将数值分段,对应数值放到对应的区域,是不是就能求出最大gap了。上面的思路就是桶排序的思想。我们建立N-1个桶,每个桶的大小为平均gap,那么最大的gap就一定发生在不同桶之间的数之间了。 具体的思路请看代码注释代码
class Solution {
public int maximumGap(int[] nums) {
//Return 0 if the array contains less than 2 elements.
if(nums.length<2)
return 0;
//find max and min
int max = nums[0];
int min = nums[1];
for (int i : nums){
max = Math.max(max,i);
min = Math.min(min,i);
}
//gap/bucket size
int gap = (int)Math.ceil((double)(max-min)/(nums.length-1));
//the number of bucket nums.length-1
//keep two array to store min and max of the bucket separately
int[] bucketmax = new int[nums.length-1];
int[] bucketmin = new int[nums.length-1];
Arrays.fill(bucketmin, Integer.MAX_VALUE);
Arrays.fill(bucketmax, Integer.MIN_VALUE);
//put num into bucket
//[min + (k-1)gap, min + k*gap).
for(int i: nums){
if(i==min||i==max)
continue;
int idx = (i-min)/gap;
bucketmax[idx] = Math.max(i,bucketmax[idx]);
bucketmin[idx] = Math.min(i,bucketmin[idx]);
}
//find max gap;
int maxgap = Integer.MIN_VALUE;
int previous = min;
for(int i=0;i<nums.length-1;i++)
{
if(bucketmin[i]==Integer.MAX_VALUE&&bucketmax[i]==Integer.MIN_VALUE)
continue;
maxgap = Math.max(maxgap,bucketmin[i]-previous);
previous = bucketmax[i];
}
maxgap = Math.max(maxgap,max-previous);
return maxgap;
}
}