- Maximum Gap
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
Return 0 if the array contains less than 2 elements.
Example
Given [1, 9, 2, 5], the sorted form of it is [1, 2, 5, 9], the maximum gap is between 5 and 9 = 4.
Challenge
Sort is easy but will cost O(nlogn) time. Try to solve it in linear time and space.
Notice
You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
解法1:bucket sorting
这题我想了半天,什么双指针,单调栈,DP都想了,最后觉得如果要时间复杂度和空间复杂度都是O(n)的话只能用类似bucket sort之类的方法。
首先是找到min和max,然后将其分成k份。这个k有讲究,不能超过n,但是也不能小于maxV-minV。所以取min(n, maxV-minV)。假如maxV-minV很小,则所有元素都挤在几个数上,那么最多也只能有maxV-minV个buckets。
然后我们分析一下就可以知道,相邻元素间隔最大值只可能是某个bucket的最大元素和下一个bucket的最小元素。那么为什么不可能是某个bucket里面的两个元素呢?因为我们将n个元素分到<=n个buckets里面,所以某个bucket最多分到一个元素!
那么可不可以分maxV-minV+1个buckets呢?可能可以,没有试。
注意:
- 特殊情况:
a. 所有元素均相同 [1,1,1,1,1,1,1],此时返回0即可。
b. 最大元素比最小元素大1 [1,1,1,1,1,2,1,1],此时返回1即可。因为maxV-minV=1,只能有1个bucket,下面的代码不适用。 - 因为map的原则都是往最近的大于等于该元素的bucket去map,最大的那个元素要特殊处理,应该map到bucket[bucketNum - 1]。
代码如下:
struct bucketType {
int count;
int minNum;
int maxNum;
bucketType(int c = 0, int minV = INT_MAX, int maxV = 0) : count(c), minNum(minV), maxNum(maxV) {}
};
class Solution {
public:
/**
* @param nums: an array of integers
* @return: the maximun difference
*/
int maximumGap(vector<int> &nums) {
int n = nums.size();
if (n < 2) return 0;
int minV = INT_MAX, maxV = INT_MIN;
for (int i = 0; i < n; ++i) {
minV = min(minV, nums[i]);
maxV = max(maxV, nums[i]);
}
//special case [1,1,1,2,1,1], [1,1,1,1,1,1]
if (maxV - minV <= 1) return maxV - minV;
int bucketNum = min(n, maxV - minV); //important!!!
int bucketLen = (maxV - minV) / bucketNum;
vector<bucketType> buckets(bucketNum);
// the buckets are [ ) range
for (int i = 0; i < n; ++i) {
int index = (nums[i] - minV) / bucketLen;
if (index >= bucketNum) index = bucketNum - 1;
buckets[index].count++;
buckets[index].maxNum = max(buckets[index].maxNum, nums[i]);
buckets[index].minNum = min(buckets[index].minNum, nums[i]);
}
int maxDist = 0;
int lastElem = buckets[0].maxNum;
for (int i = 1; i < bucketNum; ++i) {
if (buckets[i].count == 0) continue;
maxDist = max(maxDist, buckets[i].minNum - lastElem);
lastElem = buckets[i].maxNum;
}
return maxDist;
}
};