164. 最大间距

要求:把数组里的数排序找最大邻差,时空都要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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值