164. 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.
way-1:用map,时间是O(nlogn)
way-2: 用桶排序
首先对数组进行桶排序,然后找出最大的gap。
首先明确,最大的gap肯定是后桶的最小值减去前桶的最大值,注意此处说的桶均为有效桶,即不包括空桶。
因此无需进行桶内排序,仅需记录每个有效桶的最大值和最小值即可。
为何最大的gap肯定是后桶的最小值减去前桶的最大值?
假设有数组x[1...n],其中最大的元素为max,最小元素为min,将左闭右开的实数区间[min,max)划分为n-1个等长的子区间(桶),每个子区间也是左闭右开的,我们用len来表示每个子区间的长度。除去max和min,剩下的n-2个数,每个数都属于其中一个桶。对于同一个桶的两个数,因为桶是左闭右开的,所以他们的距离肯定是小于len的。然后,关键的一点是,n-2个数放进n-1个桶,由抽屉原理可以知道,肯定有一个桶是空的,所以,距离最远的相邻的两个数,肯定是属于两个不同的桶。于是,我们可以把每个桶都扫描一次,相邻最远的两个数,必定其中一个是某个桶里的最大值,另一个是另一个桶里的最小值。
class Solution {
public:
int maximumGap(vector<int>& nums)
{
if (nums.size() < 2)
return 0;
map<int,int> pp;
for (int i = 0; i < nums.size(); i++)
pp[nums[i]]++;
int ret = 0;
int lastnum = -1;
for(auto it = pp.begin(); it != pp.end(); it++)
{
if (lastnum != -1)
ret = max(ret , (it->first - lastnum) );
lastnum = it->first;
}
return ret;
}
};
class Solution {
public:
int maximumGap(vector<int>& nums)
{
if (nums.size() < 2) return 0;
int minn = INT_MAX;
int maxx = INT_MIN;
for (int i = 0; i < nums.size(); i++)
{
minn = min(minn, nums[i]);
maxx = max(maxx, nums[i]);
}
double len = (maxx - minn) * 1.0 / (nums.size() - 1); //桶的宽度
//cout<<len<<endl;
if(len == 0) return 0; //防止所有元素一样大
int cnt = floor((maxx - minn) / len + 1); //桶的个数
//cout<<cnt<<endl;
vector<int> minb(cnt, INT_MAX);
vector<int> maxb(cnt, INT_MIN);
for(int i = 0; i < nums.size(); i++) //元素分入桶
{
int id = floor((nums[i] - minn) / len);
//cout<<"id = "<<id<<endl;
minb[id] = min(minb[id], nums[i]);
maxb[id] = max(maxb[id], nums[i]);
}
int res = 0, premax = maxb[0];//第一个桶包含最小值,因此一定不为空
for(int i = 1; i < cnt; i++)
{
if(minb[i] != INT_MAX) //判断是否是空桶
{
res = max(res, minb[i] - premax);
premax = maxb[i];
}
}
return res;
}
};