Leetcode-164: 最大间距

113 阅读1分钟

题目: 最大间距

#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;

    }
};