LeetCode 164. 最大间距 2020.11.27
题目描述:
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 。
输入: [3,6,9,1]输出: 3解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
题解:
解题关键在于:
最大和最小数之间的最大间距 一定不小于(max-min)/n-1。
-
计算桶的大小:(最大值-最小值)/ 区间个数, 其中(最大-最小)即为总区间长度
-
计算桶数量:(最大值-最小值)/ 桶大小+1,(+1 的原因是,左闭右开区间)
-
计算 元素对应的桶序号: (当前元素的值-最小值)/ 桶大小
-
维护桶内的最大值,最小值
-
因为发现了,最大和最小数之间的最大间距 一定不小于(max-min)/(n-1),所以,最大间距一定出现在不同的桶之间。 所以,最后比较 当前桶的最小值与前一个桶的最大值之间的差,不断更新 最大间距。
代码:
class Solution {
// 终于,我还是来做这道题目了。终于看懂了题解。
// 桶排序 能在 O(N)内完成
public:
int maximumGap(vector<int>& nums) {
int n=nums.size();
if(n<2) return 0;
int min_num=*min_element(nums.begin(),nums.end());
int max_num=*max_element(nums.begin(),nums.end());
int len= max(1,(max_num-min_num)/(n-1)); // 与1做比较,是为了防止下一步除以len时出现异常
int bucket_num=(max_num-min_num)/len +1;
vector<pair<int,int>> bucket(bucket_num,{-1,-1});
for(auto& num: nums){
int loc= (num-min_num)/len;
if(bucket[loc].first!=-1){
bucket[loc].first=min(bucket[loc].first, num);
bucket[loc].second= max(bucket[loc].second, num);
}
else{
bucket[loc].first=num;
bucket[loc].second=num;
}
}
int pre=-1, ans=0;
for(int i=0;i<bucket_num;++i){
if(bucket[i].first==-1) continue;
if(pre!=-1){
ans=max(ans,bucket[i].first-bucket[pre].second);
}
pre=i;
}
return ans;
}
};