要求:把数组里的数排序找最大邻差,时空都要O(n)
思路:明显要计数排序桶排序
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
//如果数组元素个数小于 2,则返回 0
if(n < 2)
{
return 0;
}
vector<int> buf(n); //buf为临时顺组,用于存储每次排完序的数组
int maxVal = *max_element(nums.begin(), nums.end());
int time = maxBit(maxVal); //计算出需要最高位数,即需要排多少次
int dev = 1;
//开始从低位到高位基数排序
for(int i = 0; i < time; i++){
vector<int> count(10); //桶
//统计每个桶中有多少个数
for(int j = 0; j < n; j++){
int digit = (nums[j] / dev) % 10; //digit 为nums[j]的第i位数
count[digit] ++;
}
//此步是将count[j]由原本表示每个桶的数量,变为表示在数组中的索引
for(int j = 1; j < 10; j++){
count[j] += count[j - 1];
}
//此步对nums按照低位大小进行排序,(count[digit] - 1)表示排序后nums[j]应该在的位置
for(int j = n - 1; j >= 0; j--){
int digit = (nums[j] / dev) % 10;
buf[count[digit] - 1] = nums[j];
count[digit] --;
}
//将临时数组拷贝给nums
copy(buf.begin(),buf.end(), nums.begin());
dev *= 10;
}
//找到相邻元素最大差值
int ret = 0;
for (int i = 1; i < n; i++) {
ret = max(ret, nums[i] - nums[i - 1]);
}
return ret;
}
int maxBit(int maxVal){
int p = 10;
int d = 1;
while(maxVal >= p){
p *= 10;
d++;
}
return d;
}
};
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
if (n < 2) return 0;
// 1 计算最大值与最小值
int maxVal = *max_element(nums.begin(), nums.end());
int minVal = *min_element(nums.begin(), nums.end());
// 2 计算桶的数量,声明桶,桶内存储(桶内最小值,桶内最大值)
int bucketSize = max(1, (maxVal - minVal) / (n - 1));
int bucketNum = (maxVal - minVal) / bucketSize + 1;
vector<pair<int, int>> buckets(bucketNum, {-1, -1});
// 3 将每个元素放入桶
// 本题不用对桶里进行排序,看的是桶于桶之间的间隙
for (int num : nums) {
int idx = (num - minVal) / bucketSize;
if (buckets[idx].first == -1) {
buckets[idx].first = buckets[idx].second = num;
} else {
buckets[idx].first = min(buckets[idx].first, num);
buckets[idx].second = max(buckets[idx].second, num);
}
}
// 4 遍历桶,找最大间隙
int maxGap = 0;
int preBucket = -1;
for (int i = 0; i < bucketNum; i++) {
if (buckets[i].first == -1) continue;
if (preBucket != -1) {
maxGap = max(maxGap, buckets[i].first - buckets[preBucket].second);
}
preBucket = i;
}
return maxGap;
}
};