如果想在O(n)的时间复杂度完成这道问题,需要用到桶排序的思想。学习过后,完成了这个问题。
这道问题需要找到排序之后相邻的数字的差值的最大值。所以排序是一定的,那么桶排序是少有的能在O(n)的时间复杂度下完成排序的算法。但是对数据类型有限制。所以我们要完成向桶排序类型的转化。
继续思考,可以发现其实排序好的数据是可以分成若干段的。这就可以符合桶排序的思想。
段的划分方法:
假设排序过后的最小值为A,最大值为B,总共有N个数字,那么最后得出的最大相邻差值不会小于
(B-A)/(N-1)的向上取整。比如最小值为1,最大值100,总共有4个数。那么再怎么排列,最大差值也不会小于33(1,34,77,100)。
所以每一段可以看做一个桶,桶中的值均为同一段中的数字,所以最后的值一定出现在相邻的桶中。
A,A+(B-A)/(N-1) ,A+2*(B-1)/(N-1),。。。,B。那么只要我们记录下每个桶中的最大和最小值,就能得出最后结果。
class Solution {
public:
int maximumGap(vector<int> &nums) {
if(nums.size() < 2)
return 0;
int min_value = *std::min_element(nums.begin(),nums.end());
int max_value = *std::max_element(nums.begin(),nums.end());
int range = ceil(double(max_value - min_value)/(nums.size()-1));
if(range == 0) return 0;
vector<vector<int>> buckets(nums.size());
for(auto it = nums.begin();it != nums.end();++it)
{
int index = (*it - min_value)/range;
if(buckets[index].empty()){
buckets[index].push_back(*it);
buckets[index].push_back(*it);
}
else{
if(*it < buckets[index][0]){
buckets[index][0] = *it;
}
if(*it > buckets[index][1]){
buckets[index][1] = *it;
}
}
}
int gap = 0;
int pre = 0;
for(int i =1;i<buckets.size();++i){
if(buckets[i].empty()) continue;
gap = max(gap,buckets[i][0] - buckets[pre][1]);
pre = i;
}
return gap;
}
};