[leetcode-164]Maximum Gap(c)

本文探讨了如何在线性时间和空间复杂度下寻找未排序数组中连续元素的最大差值。通过对桶排序的理解与应用,实现了高效算法解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

Try to solve it in linear time/space.

Return 0 if the array contains less than 2 elements.

You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.

Credits:
Special thanks to @porker2008 for adding this problem and creating all test cases.

分析:这道题我没做出来,自己总结原因是,对O(n)的排序算法不了解,以前只知道快排和归并排序是O(nlogn),但并不知道桶排序的时间复杂度是O(n)。
第二对桶排序的工作原理不了解,以为是value%n然后把元素分到不同的桶里,这样是错误的。这样根本起不到排序的作用。真正的方法是,找到一个数组里面的两个极限值(最大和最小值),然后求出平均每个桶能够包容的范围gapBucket。这样,当来一个新的元素后,它的相对差(nums[i]-min)然后对gap作商即为要投放的桶。
这里会发生碰撞,(在真正排序时,还需要再桶内进行二次排序,然后再整合,但是我们这里没关系,因为一个桶内的元素的差<\gapBucket)。而我们所求的max gap一定要大于这里的gap,为啥?
反证法:如果最大的gap小于gapBucket,那么gap*(N-1)<\gapBucket*(N-1) = max-min;
与事实不符,实际上,相邻两个元素之间的值可能大于gap,也可能小于gap,但是对于大于gap的情况,一定是两个相邻的有效桶(真正有元素)之间,且后者的最小值与前者的最大值之差。一定是这种情况。

代码如下:8ms

#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        int n = nums.size();
        if(n<2)
            return 0;

        vector<int> maxBucket(n,INT_MIN);
        vector<int> minBucket(n,INT_MAX);

        int min = nums[0],max = nums[0];
        for(int i = 1;i<n;i++){
            if(nums[i]<min)
                min = nums[i];
            else if(nums[i]>max)
                max = nums[i];
        }
        double gap = (double)(max-min)/(n-1);
        for(int i = 0;i<n;i++){
            int index = (int)((nums[i]-min)/gap);
            maxBucket[index] = max(maxBucket[index],nums[i]);
            minBucket[index] = min(minBucket[index],nums[i]);
        }
        //查找有效的gap between buckets
        int res = 0;
        int prevMax = -1;
        int prevMin = -1;
        for(int i = 0;i<n;i++){
           if(maxBucket[i]<0)
                continue;
            if(prevMax>0){
                int gap = minBucket[i]-prevMax;
                if(gap>res)
                    res = gap;
            }
            prevMax = maxBucket[i];
            prevMin = minBucket[i];
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值