Osheep

时光不回头,当下最重要。

Leetcode. 数组排序之后相邻数的最大差值

问题

给定一个整型数组 arr, 返回排序后的相邻两数的最大差值.

例如:
arr = [9, 3, 1, 10], 如果排序, 结果为[1, 3, 9, 10], 9和3的差为最大差值, 故返回6.

分析

如果要做到时间复杂度为O(N), 就不能排序.
可以利用桶排序的思想,通过分桶, 将排序问题简化. 可以认为是基于分桶思想 ” 部分排序 + 统计” 的方法

  1. 将N个数分配到N+1个桶中, 做到”部分排序”
  2. 这样分桶, 必然至少有一个空的桶
    |(min) bucket 0 (max)|(min) bucket 1 (max)|(min) bucket 2 (max) |   | ... | bucket N|
  3. 每个桶维护两个值: 分到该桶中的数的最小值min和最大值max. 相邻桶(忽略空桶)的min和max即为相邻元素.
  4. 最大差值必然出现在某个或者某几个连续空桶的两侧桶的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;
    }
点赞