Leetcode. 数组排序之后相邻数的最大差值
2017-06-20 本文已影响355人
周肃
问题
给定一个整型数组 arr, 返回排序后的相邻两数的最大差值.
例如:
arr = [9, 3, 1, 10], 如果排序, 结果为[1, 3, 9, 10], 9和3的差为最大差值, 故返回6.
分析
如果要做到时间复杂度为O(N), 就不能排序.
可以利用桶排序的思想,通过分桶, 将排序问题简化. 可以认为是基于分桶思想 " 部分排序 + 统计" 的方法
- 将N个数分配到N+1个桶中, 做到"部分排序"
- 这样分桶, 必然至少有一个空的桶
|(min) bucket 0 (max)|(min) bucket 1 (max)|(min) bucket 2 (max) | | ... | bucket N|
- 每个桶维护两个值: 分到该桶中的数的最小值min和最大值max. 相邻桶(忽略空桶)的min和max即为相邻元素.
- 最大差值必然出现在某个或者某几个连续空桶的两侧桶的min和max的差值.
这样巧妙的将排序转换成为了" 桶距 "的计算.
实现
class Solution
{
public:
int maxGap(std::vector<int>& nums)
{
int size = nums.size();
if (size == 0) return 0;
int min = 0;
int max = 0;
for (auto num : nums)
{
min = std::min(min, num);
max = std::max(max, num);
}
if (min == max) return 0;
Bucket* buckets = new Bucket[size + 1];
for (auto num : nums)
{
int bucketId = getBucketId(num, size, max, min);
Bucket* bucket = &buckets[bucketId];
bucket->min = bucket->hasNum ? std::min(bucket->min, num) : num;
bucket->max = bucket->hasNum ? std::max(bucket->max, num) : num;
bucket->hasNum = true;
}
int lastMax = 0; // prev non-empty bucket's max
int bucketId = 0;
int maxGap = 0;
while (bucketId <= size)
{
Bucket* bucket = &buckets[bucketId];
if (bucket->hasNum)
{
lastMax = bucket->max;
break;
}
else
{
bucketId++;
}
}
for (bucketId++; bucketId <= size; bucketId++)
{
Bucket* bucket = &buckets[bucketId];
if (bucket->hasNum)
{
maxGap = std::max(maxGap, bucket->max - lastMax);
lastMax = bucket->max;
}
}
delete[] buckets;
return maxGap;
}