题目:https://leetcode-cn.com/problems/maximum-gap/
参考:https://leetcode-cn.com/problems/maximum-gap/solution/zui-da-jian-ju-by-leetcode/
被教育了orz
题意:给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 0。要求时间和空间复杂度为O(n)。
先来恶补下基数排序的做法_(:з」∠)_,正解在下面。
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
if(n < 2) return 0;
int lo = nums[0], hi = nums[0];
for(int i = 0;i < n;i++) {
lo = min(lo,nums[i]);
hi = max(hi,nums[i]);
}
if(hi == lo) return 0;
int base = 1;
int count[10]={};
int rank[n];
while(hi/base) {
for(int i = 0;i < 10;i++) count[i] = 0;
for(int i = 0;i < n;i++) {
count[(nums[i]/base)%10]++;
}
for(int i = 1;i < 10;i++) count[i] += count[i-1];
for(int i = n-1;i >= 0;i--)
rank[--count[(nums[i]/base)%10]] = nums[i];
for(int i = 0;i < n;i++)
nums[i] = rank[i];
base *= 10;
}
int ans = 0;
for(int i = 1;i < n;i++)
ans = max(ans,nums[i]-nums[i-1]);
return ans;
}
};
思路:找出最大值 和最小值 ,那么最理想情况下,所有数间隔都相同,此时存在最大间隔最小取值 (向上取整);那么我们可以把这n个数分块,每个块大小取 (向下取整),那么答案最大间隔值肯定是存在于块间的数,因为块内数的差值<=最大间隔最小取值。
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
if(n < 2) return 0;
int lo = nums[0], hi = nums[0];
for(int i = 0;i < n;i++) {
lo = min(lo,nums[i]);
hi = max(hi,nums[i]);
}
if(hi == lo) return 0;
int block = max(1,(hi-lo)/(n-1));//每个块大小
int sz = (hi-lo)/block+1;//总块数
int mn[sz],mx[sz];
bool vis[sz];
for(int i = 0;i < sz;i++) {
mn[i] = INT_MAX;
mx[i] = INT_MIN;
vis[i] = 0;
}
for(int i = 0,id;i < n;i++) {
id = (nums[i] - lo)/block;
vis[id] = 1;
mn[id] = min(mn[id],nums[i]);
mx[id] = max(mx[id],nums[i]);
}
int pre = lo;
int ans = 0;
for(int i = 0;i < sz;i++) {
if(!vis[i]) continue;
ans = max(ans,mn[i]-pre);
pre = mx[i];
}
return ans;
}
};