[LeetCode] Maximum Gap

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.

 

Hide Tags
 Sort
 
 鸽笼原理 (抽屉原理) “如果有五个鸽子笼,养鸽人养了6只鸽子,那么当鸽子飞回笼中后,至少有一个笼子中装有2只或2只以上鸽子。”这个简单的事实就是著名的鸽笼原理,在我们国家更多地称为抽屉原理。
 
桶排序,由于num中的数字肯定在[min,max]区间内,所以根据抽屉原理,假设num中有n个数字,则最大的gap必然要大于dis=(max-min)/(n-1),所以我们可以把num所在的范围分成等间隔的区间,相邻区间内的元素之间的最大差值,即为要寻找的gap。
 
// 用桶排序
    // 算出相邻两个桶之间的最大差值
    // 如果是平均分布,则桶的数目和元素的数目相同时,其排序的时间复杂度是0(n)
    // 我们假设桶的个数和元素的数目相同,若是平均分布,则每个桶里有一个数,而若某个桶里有两个以上的桶时,这时必有至少一个是空桶,那么最大间隔可能就落在空桶的相邻两个桶存储的数之间,最大间隔不会落在同一个桶的数里,因此我们不需要对每个桶再排一次序,只需要记录同一个桶的最大值和最小值,算出前一个有最大值的桶和后一个有最小值的桶之差,则可能是最大间隔
    //步骤:1.算好用的桶的个数,用最大元素和最小元素算出平均间隔,记录在平均间隔上的最大值和最小值,
    // 2. 再算出前一个间隔里的最大值和后一个间隔里的最小值之差,取最大的一个,

 

 

 

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <math.h>
#include <limits.h>
using namespace std;

void printArray(int *array, int size)
{
    for(int i = 0; i < size; i++)
        cout << array[i]<< "\t" ;
    cout << endl;
}


void printVector(vector<int> array )
{
    for(int i = 0; i <array.size(); i++)
        cout << array[i]<< "\t" ;
    cout << endl;
}

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

            int maxVal = nums[0];
            int minVal = nums[0];

            for(int i = 1; i < n; i++)
            {
                maxVal = max(maxVal, nums[i]);
                minVal = min(minVal, nums[i]);
            }

            // n nums has (n-1) the gap ;
            // average gap = (maxVal - minVal) / (n-1);
            // so the minimum of max gap is ceilOf(average gap);
            int minOfMaxGap = ceil((double)(maxVal - minVal) /(n - 1));

            // bucket number, the last bucket may contains the maxVal 
       // 求bucketCnt+1的意义是保存最大值。。就是吧maxVa放在最后一个bucket中
// 如果(maxVal-minVal)能够整除minOfMaxGap,那么maxVal在最后一个bucket, // 如果(maxVal-minVal)能够整除minOfmaxGap,那么maxVal在倒数第二个öbucket int bucketCnt = ceil((double)(maxVal - minVal)/minOfMaxGap) + 1; // for numbers in a same bucket, its max gap is minOfMaxGap, // So the maxGap occur at different buckets, including emtpy buckets // we record maxVal and minVal in every bucket vector<int> maxVec(bucketCnt, INT_MIN); vector<int> minVec(bucketCnt, INT_MAX); int idx = 0; for(int i = 0; i < n; i ++) { idx = (nums[i] - minVal)/minOfMaxGap; if(maxVec[idx] < nums[i]) maxVec[idx] = nums[i]; if(minVec[idx] > nums[i]) minVec[idx] = nums[i]; } //cout << "minOfMaxGap\t" << minOfMaxGap << endl; //cout << "bucketCnt\t"<< bucketCnt<< endl; //cout << "maxVec\t"; //printVector(maxVec); //cout << "minVec\t"; //printVector(minVec); int maxGap = minOfMaxGap; int preMax = maxVec[0]; for(int i = 1; i < bucketCnt; i++) { if(minVec[i] == INT_MAX)// empty bucket continue; if(minVec[i] - preMax > maxGap) { maxGap = minVec[i] - preMax; } preMax = maxVec[i]; } return maxGap; } }; int main() { vector<int> nums; nums.push_back(3); nums.push_back(6); nums.push_back(9); nums.push_back(1); Solution sl; cout << sl.maximumGap(nums) <<endl; return 0; }

 

posted @ 2015-07-13 18:08  穆穆兔兔  阅读(387)  评论(0编辑  收藏  举报