[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.
鸽笼原理 (抽屉原理) “如果有五个鸽子笼,养鸽人养了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; }