这道题可以有两种刚解法:
解法一:
基于bucket sort的方法:
有n个未排序的数字。
1、先求出数组内最大数max和最小数min。
2、求出每个桶内的数字范围:gap = (max - min) / (n - 1)。
3、算出桶的数量: N = (max - min)/ gap + 1 (可知 N >= n)
每个桶对应的数字范围为:
第一个:[min, min + gap)
第二个:[min + gap, min + 2*gap)
......
第N个:[min + (N-1)gap, min + N*gap)
由于至少有n个桶。因此最平均的情况是每个桶里一个数字。这时是要算出每个相邻桶内数字的差即可得出结果。
若数字分布不均匀,有若干个数字在同一个桶内。那么一定起码有一个桶是空的。存在两个相邻数字的差 > gap 。
因此只要通过记录每个桶内最大数,和最小数。然后通过不断比较第i个桶的最小值与前一个非空桶的最大值的差值,即可得到结果。
code如下:
class Solution {
public:
int maximumGap(vector<int>& nums) {
if (nums.size() < 1) return 0;
int res = 0;
int maxV = INT_MIN, minV = INT_MAX, n = nums.size();
for (auto i : nums) {
maxV = max(maxV, i);
minV = min(minV, i);
}
if (maxV == minV) return 0;
int gap = (maxV - minV) / (n - 1) > 0 ? (maxV - minV) / (n - 1) : 1;
int bucketNum = (maxV - minV) / gap + 1;
int *bucketMin = new int[bucketNum], * bucketMax = new int[bucketNum];
for (int i = 0; i < bucketNum; i++) {
bucketMin[i] = INT_MAX;
bucketMax[i] = INT_MIN;
}
for (auto i : nums) {
bucketMin[(i - minV) / gap] = min(i, bucketMin[(i - minV) / gap]);
bucketMax[(i - minV) / gap] = max(i, bucketMax[(i - minV) / gap]);
}
int preIndex = 0;// 前一个非空桶的下标
for (int i = 1; i < bucketNum; i++){
if (bucketMin[i] == INT_MAX) continue;
res = max(bucketMin[i] - bucketMax[preIndex], res);
preIndex = i;
}
return res;
}
};
方法二:
用radix sort先将整个数组排序。
radix sort的原理可以参考:
https://www.cs.usfca.edu/~galles/visualization/RadixSort.html
code:
class Solution {
public:
int maximumGap(vector<int>& nums) {
if (nums.size() < 2) return 0;
int res = 0, digit = 1, maxNum = INT_MAX;
while(maxNum) {
digit++;
maxNum /= 10;
}
long k = 10;
for (int j = 1 ; j <= digit; j++, k *= 10) {
vector<int> tmp(nums.size(), 0);
int count[10] = {0};
for (auto num : nums) {
count[num % k / (k / 10)]++;
}
for(int i = 1; i < 10; i++)
count[i] += count[i - 1];
for (int i = nums.size() - 1; i >=0; i--) {
int digit = nums[i] % k / (k / 10);
tmp[count[digit] - 1] = nums[i];
count[digit]--;
}
nums = tmp;
}
for (int i = 1; i < nums.size(); i++)
res = max(nums[i] - nums[i - 1], res);
return res;
}
};