164. 最大间距
给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。
您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。
示例 1:
输入: nums = [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9)
之间都存在最大差值 3。
示例 2:
输入: nums = [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。
提示:
1 <= nums.length <= 1e5
0 <= nums[i] <= 1e9
解析
1,可以直接排序时间复杂度O(N)
2,利用桶排序,n个数相邻两个数之间的最大值的最小距离不会小于d=⌈(max−min)/(N−1)⌉,最小距离就是的时候就是等差数列情况:2 4 6 8.
3,因此可以使用桶排序,将数据分桶,桶的个数为bucketSize = (maxVal - minVal) / d + 1;
4,然后将数据放入对应桶中,此时桶内存放数据的最大距离小于d,由(2)知,两数的最小距离为d,因此最大距离应该在桶与桶之间。
5,只需要记住每个桶的最大值,最小值即可
例如:2 4 6 8 ,d=2 , bucketsize=4 (此时正好整除可以使用三个桶就可以了,如果整除不了,桶的大小就要+1.)
code
class Solution {
public:
int maximumGap(vector<int>& nums) {
// bucket
int n=nums.size();
if(n<2)
return 0;
int maxv=*max_element(nums.begin(),nums.end());
int minv=*min_element(nums.begin(),nums.end());
// 最大距离的最小值
int d=max(1,(maxv-minv)/(n-1));
// 桶个数(可以多用几个桶也无所谓,不会存放内容)
int bucket_size=(maxv-minv)/d+1;
vector<pair<int,int>> bucket(bucket_size,{-1,-1});
for(auto a:nums){
// 将范围内的距离放到对应桶内,每个桶的长度为d
int idx=(a-minv)/d;
if(bucket[idx].first==-1)
bucket[idx].first=a;
else
bucket[idx].first=min(bucket[idx].first,a);
bucket[idx].second=max(bucket[idx].second,a);
}
int pre=0,res=0;
for(int i=1;i<bucket_size;i++){
// 数据分布不均匀中间会有空桶0 1 100
if(bucket[i].first==-1)
continue;
res=max(bucket[i].first-bucket[pre].second,res);
pre=i;
}
return res;
}
};