zoukankan      html  css  js  c++  java
  • 【leetcode 桶排序】Maximum Gap

    1、题目

    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.


    2、分析

    题意:给定一个未排序的数组。返回其排序后的数组中 相邻元素之差 最大的值。

    比方给定:[5,9,8,3,15]

    排序后为:[3,5,8,9,15]。相邻元素之差最大的是15-9=6,返回6。

    复杂度要求:时间空间均为O(n)。


    这道题最直接的解法是,先排序,得到有序数组。然后再对相邻元素作差。找出差最大的,比方以下简短的代码:

    class Solution {
    public:
        int maximumGap(vector<int> &num) {
            if(num.size()<2) return 0;
            sort(num.begin(),num.end()); //O(nlogn)
            int gap=-1;
            for(int i=1;i<num.size();i++){
                gap=max(gap,num[i]-num[i-1]);
            }
            return gap;
        }
    };

    在Leetcode上上面的代码能够AC,但其实并没有满足时间复杂度要求。由于STL函数sort()的复杂度是O(nlogn),【sort C++ reference】


    那么。线性的排序算法有哪些?计数排序、基数排序、桶排序。

    以下用桶排序实现。这也是leetcode上给出的參考解法。我直接copy过来:


    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) {
           if (num.size() < 2) return 0;
            //遍历一遍。找出最大最小值
            int maxNum = num[0];
            int minNum = num[0];
            for (int i : num) {
                maxNum=max(maxNum,i);
                minNum=min(minNum,i);
            }
            // 每一个桶的长度len,向上取整所以加+
            int len = (maxNum - minNum) / num.size() + 1;
            
            //桶的个数:(maxNum - minNum) / len + 1,每一个桶里面存储属于该桶的最大值和最小值就可以,注意这里的最大最小值是局部的
            vector<vector<int>> buckets((maxNum - minNum) / len + 1);
            for (int x : num) {
                int i = (x - minNum) / len;
                if (buckets[i].empty()) {
                    buckets[i].reserve(2);
                    buckets[i].push_back(x);
                    buckets[i].push_back(x);
                } else {
                    if (x < buckets[i][0]) buckets[i][0] = x;
                    if (x > buckets[i][1]) buckets[i][1] = x;
                }
            }
            //gap的计算,For each non-empty buckets p, find the next non-empty buckets q, return min( q.min - p.max )
            int gap = 0;
            int prev = 0;
            for (int i = 1; i < buckets.size(); i++) {
                if (buckets[i].empty()) continue;
                gap = max(gap, buckets[i][0] - buckets[prev][1]);
                prev = i;
            }
            return gap;
        }
    };



    【其它解法以后再更新】


  • 相关阅读:
    iOS面试题
    iOS-block
    iOS开发设计模式
    iOS-宏定义
    正则表达式(转)
    iOS-textfield控制光标开始位置
    initWithNibName&initWithCoder &awakeFromNib&UIView常见属性方法
    iOS应用生命周期
    iOS-app发布新版本步骤
    iOS从App跳转至系统设置菜单各功能项
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6697530.html
Copyright © 2011-2022 走看看