思路:
桶排序+抽屉原理。
桶排序:类似map-reduce中对结果集进行全排序的想法,到第一个reducer的数据的最大值要小于到达第二个reducer数据的最小值,这里每reducer就相当于一个桶。桶间的数据在划分该数据属于哪个桶时就相当于一次排序,桶内的数据再利用快排或者其它比较排序的方法进行排序,之后达到整体有序的状态。
极限情况,若有n个数据,那么通过创建n个桶,可以在O(n)的时间复杂度范围内进行排序。
一般情况,若有n个数据,创建了m个桶,将每个数据分到一个桶中需要O(n),每个桶内排序需要O(m * n/m * log(n/m)),所以一共需要 O(n) + O(m * n/m * log(n/m)) = O(n+n*logn-n*logm)
。此时,若 n == m
,就为极限情况。
抽屉原理:10个数放在100个抽屉中,最少也得有90个空抽屉,空抽屉就相当于gap。
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
if(n < 2) return 0;
if(n == 2) return abs(nums[0] - nums[1]);
int array_min = nums[0], array_max = nums[0];
for(int i = 1; i < n; ++i) {
array_min = min(array_min, nums[i]);
array_max = max(array_max, nums[i]);
}
int dist = (array_max - array_min) / n + 1;
vector<vector<int>> bucket((array_max - array_min) / dist + 1);
int idx;
for(int i = 0; i < n; ++i) {
idx = (nums[i] - array_min) / dist;
if(bucket[idx].empty()) {
bucket[idx].push_back(nums[i]);//this bucket's min element
bucket[idx].push_back(nums[i]);//this bucket's max element
}else {
bucket[idx][0] = min(bucket[idx][0], nums[i]);
bucket[idx][1] = max(bucket[idx][1], nums[i]);
}
}
int gap = 0, pre = 0, tmp;
for(int i = 1; i < bucket.size(); ++i) {
if(bucket[i].empty()) continue;
tmp = bucket[i][0] - bucket[pre][1];
gap = max(gap, tmp);
pre = i;
}
return gap;
}
};