這道題可以有兩種剛解法:
解法一:
基於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;
}
};