[Lintcode] Maximum Gap Problem

35 篇文章 0 订阅
24 篇文章 0 订阅

问题描述

在一个无序的数组中,如果对其进行排序,然后扫描一遍有序数组,可以获得相邻两元素的最大差值,比如 {-1, 2, 4, 9},那么最大差值就是4和9之间,是5.
现在如果不对原始数组进行排序,有什么好的方案,来获取有序形式下的最大差值?
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

Return 0 if the array contains less than 2 elements.

问题求解

此问题还是基于桶排序的概念。可以申请一系列桶,每个桶装下某一个子区间的元素。
假设所有元素中最大值是maxNum, 最小是minNum,元素个数是n,那么平均gap就是 (maxNum-minNum)/n,如果gap是小数,则上取整。那么每个桶应该就负责长度为gap的子区间。 总的桶的数量也是 O(n)。

具体代码如下:

class Solution {
public:
    /**
     * @param nums: a vector of integers
     * @return: the maximum difference
     */
    int maximumGap(vector<int> nums) {
        int n = nums.size();
        if (n < 2) return 0;
        int maxNum = nums[0], minNum = nums[1];
        for (int i = 0; i < n; i++) {
            maxNum = max(maxNum, nums[i]); minNum = min(minNum, nums[i]);
        }
        if (maxNum == minNum) return 0;
        int gap = ceil((maxNum-minNum)*1.0/(n-1));
        int bucket_size = (maxNum - minNum) / gap + 1;
        vector<vector<int> > buckets(bucket_size);
        for (int i = 0; i < n; i++) {
            int idx = (nums[i] - minNum) / gap;
            if (buckets[idx].size() == 0) {
                buckets[idx].push_back(nums[i]); buckets[idx].push_back(nums[i]);
            } else {
                buckets[idx][0] = min(buckets[idx][0], nums[i]); buckets[idx][1] = max(buckets[idx][1], nums[i]);
            }
        }
        //for (int i = 0; i < buckets.size(); i++) { for (int j = 0; j < buckets[i].size(); j++) printf("%d ", buckets[i][j]); printf("#\n"); }
        int ans = 0, pre = -1;
        for (int i = 0; i < buckets.size(); i++) {
            if (buckets[i].size() == 0) continue;
            ans = max(ans, buckets[i][1] - buckets[i][0]);
            if (pre != -1) ans = max(ans, buckets[i][0] - buckets[pre][1]);
            pre = i;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值