题目: 最大间距
#include<cmath>
class Solution {
public:
// 基数排序, 步骤如下:
// 1、找出最大值(数组中存在负数的话应该找出位数最大值)
// 2、计算最大值长度
// 3、LSD: 使用倒数遍历计数排序进行最低位优先基数排序
int maximumGap(vector<int>& nums) {
// 1. 我们先要排除特殊case, 当数组中只有1个或者0个元素的时候, 直接返回0
if(nums.size()<=1) return 0;
// 2. 遍历我们的nums, 来获取nums里面最大值
int max_val = 1 << 31;
for(auto num : nums) {
if (num > max_val) {
max_val= num;
}
}
//3. 从最大值的身上算出最大值是几位数
int max_len =0;
while (max_val != 0) {
max_len++;
max_val /= 10;
}
// 4. 遍历轮数(最大位数)
vector<int> counting;
vector<int> result;
int dev = 1;
for (int i=0; i<max_len; i++) {
// 在每一位数的轮次内, 计算各个 数值都出现了几次
// 每次都初始化一下, counting 重新重置都为0
counting.assign(10, 0);
// result也全清空
result.resize(nums.size());
// 这个时候我们需要去从每一项的最低位开始基数排序
for (int elment : nums) {
// 拿到每一个 element的 第dev分位的radix
int radix = elment / dev % 10;
counting[radix]++;
}
// 这一步关键: 我们需要遍历我们的统计, 这个时候每一个counting位置 (i) 都有 counting[i]个数要小于该i
for (int i=1; i<counting.size(); i++) {
counting[i] += counting[i-1];
}
// 第二步的关键点: 基数排序的核心
for(int i = nums.size()-1 ; i>=0; i--) {
// 拿到我们的基数
int radix = nums[i] / dev % 10;
// 根据基数所在的counting位置, 找到在result的位置, 并把nums[i]赋值到该位置上
// 分析:
// 1. counting[radix]的值表示的是该radix应该是在第几位上
// 2. 假设 couning[radix], 是4, 那就说明, 该 radix是排在第4的
// 3. 所以 position应该是3 (counting[radix] -1 获取的);
// 也就是说明他是数组里面排在 result[position] (result[3]) 的位置
// (0,1,2,3), 正好是第4位;
// 4. 同时 counting[radix] = counting[radix]-1, 因为拿出来了一个放在result里面了,
// 所以计数的counting[radix]的值应该是-1
int position = counting[radix]-1;
result[position] = nums[i];
counting[radix]--;
}
// 要把 result 给 nums, 因为这个是我们这个dev分位排好序的
nums.swap(result);
dev *=10;
}
// 此时代码走到这里 nums已经排好了顺序
// 是按照从小到大排列的(因为我们的counting是记录 counting[i]个数要小于该i)
int recorder = 0;
for(int i=1; i<nums.size() ; i++){
int diff = nums[i] - nums[i - 1];
if (diff > recorder) recorder = diff;
}
return recorder;
}
};