题目描述:
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
示例 1:
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。
说明:
你可以假设数组中所有元素都是非负整数,且数值在 32 位有符号整数范围内。
请尝试在线性时间复杂度和空间复杂度的条件下解决此问题。
方法1:
主要思路:
(1)使用桶排序;
(2)使用桶排序,需要先找出给出的数组中的最大值max_num和最小值min_num,然后根据数组内元素的范围,设定合适大小的桶,这里由于是要求相邻的元素之间最大的差值,则这个最大的差值理论上最小的情况是各个元素之间成等差数列分布,则此时的等差大小,即可为此时的桶的大小,既step=(max_num-min_num)/(nums.size()-1)>1?(max_num-min_num)/(nums.size()-1):1;
(3)然后确定桶的数量,则在上述情形下,理论上的桶中每个包括一个元素的情形时,桶的数量为(max_num-min_num)/step+1,而桶中需要保存的数据是应该存入到桶中的所有的数据的最小值和最大值,故总的桶为vector<pair<int,int>> buckets((max_num-min_num)/step+1,pair<int,int>(INT_MAX,INT_MIN));然后遍历原数组,将数组中的元素对应的放入到相应的桶中,这里就是对应的更新相应的桶中最大值和最小值即可,遍历完数组,既完成了桶排序;
(4)进行完桶排序之后,需要找出最大的间隔,则间隔可能出现的位置是在相邻桶中,后一个桶的最小值和前一个桶的最大值之差,遍历完桶,既获得最大的间距;
class Solution {
public:
int maximumGap(vector<int>& nums) {
if(nums.size()<2){//特殊的情形
return 0;
}
//保存数组中的最大值和最小值
int min_num=INT_MAX;
int max_num=INT_MIN;
for(int&num:nums){
min_num=min(min_num,num);
max_num=max(max_num,num);
}
//求出桶的大小
int step=(max_num-min_num)/(nums.size()-1)>1?(max_num-min_num)/(nums.size()-1):1;
vector<pair<int,int>> buckets((max_num-min_num)/step+1,pair<int,int>(INT_MAX,INT_MIN));//确定桶的数量,构造桶存储结构
for(int& num:nums){//遍历数组,进行桶排序
int index=(num-min_num)/step;//确定当前数组元素应该分到的桶的对应的索引
//更新桶中的最大值和最小值
buckets[index].first=min(buckets[index].first,num);
buckets[index].second=max(buckets[index].second,num);
}
//使用第一桶中的值初始化
int res=0;//保存结果
int pre_max=buckets[0].second;//存储当前桶的前一个桶中的最大值
for(int i=1;i<buckets.size();++i){//遍历桶
if(buckets[i].first!=INT_MAX){//保证当前桶中有有效的元素
res=buckets[i].first-pre_max>res?buckets[i].first-pre_max:res;//当前桶和前一个桶的间隔
pre_max=buckets[i].second;//当前桶的前一个桶中的最小的元素
}
}
return res;
}
};