给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
示例 1:
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。
说明:
你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。
思路分析:需要知道最大间距,那么一般来说是要先进行排序的,时间复杂度为O(n)的排序方法中,好像我就知道计数排序、桶排序。
方法一:使用map容器辅助,进行计数排序。(但是map自动排序的复杂度貌似是O(nlogn))
class Solution {
public:
int maximumGap(vector<int>& nums) {
int numsSize = nums.size();
if (numsSize < 2) {
return 0;
}
map<int, int> myMap;//辅助容器,用于标记各个元素的出现的次数
//扫描nums
for (int index = 0; index < numsSize; ++index) {
++myMap[nums[index]];
}
int maxGap = 0;//存放结果
map<int, int>::iterator before = myMap.begin();
//再次扫描容器,判断排序好的左右两端的间距差
for (map<int, int>::iterator it = ++myMap.begin(); it != myMap.end(); ++it) {
int tempValue = it->first - before->first;
maxGap = max(maxGap, tempValue);//更新结果
++before;
}
return maxGap;
}
};
方法二:使用桶排序,但不建立正真的桶,而是虚设的桶,只保留桶中的最大值、最小值。桶的数量为nums.size() + 1,所以每个桶至多只有一个元素,(且最小值放在第一个桶,最大值放在最后一个桶),只设立每个桶的最大值、最小值变量。再将所有元素都放入它应该在的桶序号,最后扫描所有的桶,求出间距。
class Solution {
public:
//将 num 映射到对应的桶子
int mapToBucket(long num, long len, long min, long max) {
return (int) ((num - min) * len / (max - min));
}
int maximumGap(vector<int>& nums) {
int numsSize = nums.size();
if (numsSize < 2) {
return 0;
}
int maxValue = *max_element(nums.begin(), nums.end());//获取桶中的最大值
int minValue = *min_element(nums.begin(), nums.end());//获取桶中的最小值
if (maxValue == minValue) {
return 0;
}
int bucketCnt = numsSize + 1;//桶的个数
vector<int> maxBucket(bucketCnt, INT_MIN);//新建长度bucketSize的vector容器,maxBucket[i]用于保存第i个桶的最大值
vector<int> minBucket(bucketCnt, INT_MAX);//新建长度bucketSize的vector容器,minBucket[i]用于保存第i个桶的最小值
maxBucket[0] = minBucket[0] = minValue;//第一个桶只保存最小值
maxBucket[bucketCnt - 1] = minBucket[bucketCnt - 1] = maxValue;//最后一个桶只保存最大值
for (auto num : nums) {
int bucketIndex = mapToBucket(num, numsSize, minValue, maxValue);//这个元素应该放的桶的序号
maxBucket[bucketIndex] = max(maxBucket[bucketIndex], num);//更新这个桶中的最大值
minBucket[bucketIndex] = min(minBucket[bucketIndex], num);//更新这个桶中的最小值
}
int maxGap = INT_MIN, preIndex = 0;
//扫描所有的桶,计算桶之间的间距
for (int index = 1; index < bucketCnt; ++index) {
//跳过空桶
while (preIndex < bucketCnt && maxBucket[preIndex] == INT_MIN) {
++preIndex;
}
if (preIndex == bucketCnt) {
break;
}
index = preIndex + 1;
//跳过空桶
while (index < bucketCnt && maxBucket[index] == INT_MIN) {
++index;
}
if (index == bucketCnt) {
break;
}
//更新间距
maxGap = max(maxGap, minBucket[index] - maxBucket[preIndex]);
preIndex = index;
}
return maxGap;
}
};