这道题首先一定要有“排序”的思想,但是常用的排序算法复杂度至少是O(NlogN),不满足题意。进一步思考可以得出,这里的“排序”不一定非要“完整排序”,可以只要“部分排序”即可,这可以想到桶排序,只要意识到了桶排序,这道题就解决了一大半。
由于平时桶排序思路接触的比较少,还是在unlock了solution后根据给出的提示才解出来。
提示如下:
Suppose there are N elements and they range from A to B.
Then the maximum gap will be no smaller than ceiling[(B - A) / (N - 1)]
Let the length of a bucket to be len = ceiling[(B - A) / (N - 1)], then we will have at most num = (B - A) / len + 1 of bucket
for any number K in the array, we can easily find out which bucket it belongs by calculating loc = (K - A) / len and therefore maintain the maximum and minimum elements in each bucket.
Since the maximum difference between elements in the same buckets will be at most len - 1, so the final answer will not be taken from two elements in the same buckets.
For each non-empty buckets p, find the next non-empty buckets q, then q.min - p.max could be the potential answer to the question. Return the maximum of all those values.
class Solution {
public:
int maximumGap(vector<int> &num) {
int n=num.size();
if(n<2)
{
return 0;
}
int max=num[0];
int min=num[0];
for(int i=0;i<n;++i)
{
if(num[i]>max)
{
max=num[i];
}
if(num[i]<min)
{
min=num[i];
}
}
int bucketLen=(max-min+n-1-1)/(n-1);//max gap must bigger than this value
int bucketCnt=(max-min)/bucketLen+1;
vector<int> bucketMax(bucketCnt,-1);//there are at most n bucket
vector<int> bucketMin(bucketCnt,(1<<31)-1);
//every num located in one bucket,and because every bucket is at most bucketLen,so nums in the same bucket have the biggest difference bucketLen,which is impossible the max gap(max gap is bigger than bucktLen)
for(int i=0;i<n;++i)
{
int pos=(num[i]-min)/bucketLen;
if(num[i]>bucketMax[pos])
{
bucketMax[pos]=num[i];
}
if(num[i]<bucketMin[pos])
{
bucketMin[pos]=num[i];
}
}
int maxGap=0;
int preMax=-1;
for(int i=0;i<bucketCnt;++i)
{
if(bucketMax[i]!=-1)
{
if(preMax==-1)
{
preMax=bucketMax[i];
}
else
{
int tmp=bucketMin[i]-preMax;
if(tmp>maxGap)
{
maxGap=tmp;
}
preMax=bucketMax[i];
}
}
}
return maxGap;
}
};