###问题描述
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.
解法一:
这道题最直接的解法是,先排序,得到有序数组,然后再对相邻元素作差,找出差最大的,比如下面简短的代码:
class Solution {
public:
int maximumGap(vector<int> &num) {
if(num.size()<2) return 0;
sort(num.begin(),num.end()); //O(nlogn)
int gap=-1;
for(int i=1;i<num.size();i++){
gap=max(gap,num[i]-num[i-1]);
}
return gap;
}
};
在Leetcode上上面的代码可以AC,但事实上并没有满足时间复杂度要求。因为STL函数sort()的复杂度是O(nlogn)。
那么,线性的排序算法有哪些?计数排序、基数排序、桶排序。
下面用桶排序实现,这也是leetcode上给出的参考解法,我直接copy过来:
解法二
class Solution {
public:
int maximumGap(vector<int>& nums) {
if(nums.size() < 2 ) return 0;
auto temp = std::minmax_element(nums.begin(), nums.end());
int l = *temp.first;
int u = *temp.second;
int bucket_gap = (u-l)/(nums.size()-1) >1? (u-l)/(nums.size()-1):1;
int bucket_num = (u-l)/bucket_gap +1 ;
std::vector<int> bucket_min(bucket_num,INT_MAX);
std::vector<int> bucket_max(bucket_num,INT_MIN);
for(auto num : nums) {
int k = (num - l)/bucket_gap;
bucket_min[k] = min(num,bucket_min[k]);
bucket_max[k] = max(num,bucket_max[k]);
}
int i = 0;
int gap = bucket_max[0] - bucket_min[0];
while(i < bucket_num-1) {
int j = i+1;
// check the jth bucket whether contains a num or not
while (j < bucket_num && bucket_max[j] == INT_MIN && bucket_min[j] == INT_MAX)
j++;
if(j==bucket_num) break;
gap = max(gap, bucket_min[j] - bucket_max[i]);
i = j;
}
return gap;
}
};
比较有意思的是std::minmax_element
函数,可以直接得到最小值和最大值。