题目链接:https://leetcode.com/problems/maximum-gap/
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
Return 0 if the array contains less than 2 elements.
Example 1:
Input: [3,6,9,1] Output: 3 Explanation: The sorted form of the array is [1,3,6,9], either (3,6) or (6,9) has the maximum difference 3.
Example 2:
Input: [10] Output: 0 Explanation: The array contains less than 2 elements, therefore return 0.
Note:
- You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
- Try to solve it in linear time/space.
思路一:
快速排序后寻找,时间复杂度O(nlogn)
AC 4ms:
class Solution {
public int maximumGap(int[] nums) {
if(nums==null||nums.length<=1)
return 0;
Arrays.sort(nums);
int ans=0;
for(int i=1;i<nums.length;i++){
ans=Math.max(ans,nums[i]-nums[i-1]);
}
return ans;
}
}
思路二:
看了下官方解释,大体是桶排序的思路,只不过用了更多技巧性的东西。
比如一共有N个数,最大max,最小min,那么分派N+1个桶子,保证肯定有一个桶为空的,而且min在第0个桶,
max在第N个桶。这样的话只需保存每个桶里面的最大值最小值以及该桶是否有num落入其中,
间距的最大值一定不在同一个桶里面,这样只需计算一个桶的最小值和它的前一个非空桶的最大值。
因为桶的范围间距为(max-min)/N;
同一个桶里面的数最大值与最小值的差小于该间距。
下面借用一张图更直观的理解:
AC 2ms:
class Solution {
public int maximumGap(int[] nums) {
if(nums==null||nums.length<=1)
return 0;
int max=nums[0],min=nums[0];
for(int num:nums){
max=Math.max(num,max);
min=Math.min(num,min);
}
if(max==min)
return 0;
int[] minB=new int[nums.length+1];
int[] maxB=new int[nums.length+1];
boolean[] hasNum=new boolean[nums.length+1];
for(int i=0;i<nums.length;i++){
int index=mapToBucket(nums[i],nums.length,min,max);
minB[index]=hasNum[index]?Math.min(minB[index],nums[i]):nums[i];
maxB[index]=hasNum[index]?Math.max(maxB[index],nums[i]):nums[i];
hasNum[index]=true;
}
int ans=0;
int prev=min;
for(int i=0;i<nums.length+1;i++){
if(!hasNum[i])
continue;
ans=Math.max(ans,minB[i]-prev);
prev=maxB[i];
}
ans=Math.max(ans,max-prev);
return ans;
}
public int mapToBucket(long num, long len, long min, long max) {
return (int) ((num - min) * len / (max - min));
}
}