Maximum Gap

这道题首先一定要有“排序”的思想,但是常用的排序算法复杂度至少是O(NlogN),不满足题意。进一步思考可以得出,这里的“排序”不一定非要“完整排序”,可以只要“部分排序”即可,这可以想到桶排序,只要意识到了桶排序,这道题就解决了一大半。

由于平时桶排序思路接触的比较少,还是在unlock了solution后根据给出的提示才解出来。

提示如下:

Suppose there are N elements and they range from A to B.

Then the maximum gap will be no smaller than ceiling[(B - A) / (N - 1)]

Let the length of a bucket to be len = ceiling[(B - A) / (N - 1)], then we will have at most num = (B - A) / len + 1 of bucket

for any number K in the array, we can easily find out which bucket it belongs by calculating loc = (K - A) / len and therefore maintain the maximum and minimum elements in each bucket.

Since the maximum difference between elements in the same buckets will be at most len - 1, so the final answer will not be taken from two elements in the same buckets.

For each non-empty buckets p, find the next non-empty buckets q, then q.min - p.max could be the potential answer to the question. Return the maximum of all those values.



class Solution {
public:
    int maximumGap(vector<int> &num) {
        int n=num.size();
        if(n<2)
        {
            return 0;
        }
        int max=num[0];
        int min=num[0];
        for(int i=0;i<n;++i)
        {
            if(num[i]>max)
            {
                max=num[i];
            }
            if(num[i]<min)
            {
                min=num[i];
            }
        }
        int bucketLen=(max-min+n-1-1)/(n-1);//max gap must bigger than this value
		int bucketCnt=(max-min)/bucketLen+1;
        vector<int> bucketMax(bucketCnt,-1);//there are at most n bucket
        vector<int> bucketMin(bucketCnt,(1<<31)-1);
        //every num located in one bucket,and because every bucket is at most bucketLen,so nums in the same bucket have the biggest difference bucketLen,which is impossible the max gap(max gap is bigger than bucktLen)
        for(int i=0;i<n;++i)
        {
            int pos=(num[i]-min)/bucketLen;
            if(num[i]>bucketMax[pos])
            {
                bucketMax[pos]=num[i];
            }
            if(num[i]<bucketMin[pos])
            {
                bucketMin[pos]=num[i];
            }
        }
        int maxGap=0;
        int preMax=-1;
        for(int i=0;i<bucketCnt;++i)
        {
            if(bucketMax[i]!=-1)
            {
                if(preMax==-1)
                {
                    preMax=bucketMax[i];
                }
                else
                {
                    int tmp=bucketMin[i]-preMax;
                    if(tmp>maxGap)
                    {
                        maxGap=tmp;
                    }
                    preMax=bucketMax[i];
                }
            }
        }
        return maxGap;
        
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述: 给定一个无序的数组 nums,返回数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 0。 要求: 你必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例: 输入: [3,6,9,1] 输出: 3 解释: 排序后的数组是 [1,3,6,9],其中相邻元素 (3,6) 和 (6,9) 之间都存在 3 的差值。 解题思路: 要求线性时间和空间,可以想到桶排序。首先遍历一遍数组,找到最大值和最小值,确定桶的大小和数量。将元素按照一定的规则放入桶中,然后在桶内寻找相邻元素之间的最大差值。 由于题目要求相邻元素之间的最大差值,因此可以将桶的大小设为 max(1, (max-min)/(n-1)),其中 n 为数组的长度,这样可以保证桶内相邻元素之间的差值不会超过桶的大小。 放入桶中的规则可以是:假设桶的数量为 n,那么第 i 个元素所在的桶的编号为 (num[i]-min) * n / (max-min),这样就可以保证相邻元素在同一个桶中,而不同的桶之间一定存在空桶。 放入桶中后,从左到右依次遍历桶,用当前桶的最小值减去前一个桶的最大值,得到相邻元素之间的差值,取最大值即可。 Python代码实现: ```python class Solution: def maximumGap(self, nums: List[int]) -> int: n = len(nums) if n < 2: return 0 # 找到最大值和最小值 max_num, min_num = max(nums), min(nums) # 计算桶的大小和数量 bucket_size = max(1, (max_num - min_num) // (n - 1)) bucket_num = (max_num - min_num) // bucket_size + 1 # 初始化桶 bucket = [[float('inf'), float('-inf')] for _ in range(bucket_num)] for num in nums: # 计算元素所在的桶的编号 idx = (num - min_num) // bucket_size # 更新桶的最大值和最小值 bucket[idx][0] = min(bucket[idx][0], num) bucket[idx][1] = max(bucket[idx][1], num) # 遍历桶,计算相邻元素之间的最大差值 res, pre_max = 0, bucket[0][1] for i in range(1, bucket_num): if bucket[i][0] == float('inf'): continue res = max(res, bucket[i][0] -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值