力扣(LeetCode)164. 最大间距(C++)

桶排序(划分区间)

一次遍历找到区间内最大值 M a x Max Max ,最小值 M i n Min Min 。区间 ( M i n , M a x ] (Min,Max] (Min,Max] 左开右闭,划分为 n − 1 n-1 n1 个长度为 l e n len len 的区间 ,划分的区间左开右闭,所以每个子区间有 l e n − 1 len-1 len1 个数。
根据实际意义,
( n − 1 ) ( l e n − 1 ) ≤ M a x − M i n − 1 (n-1)(len-1)\le Max - Min -1 (n1)(len1)MaxMin1 时,答案一定不在某个子区间内部取到。
整理上式,得,
l e n ≤ ⌊ M a x − M i n + n − 2 n − 1 ⌋ = ⌈ M a x − M i n n − 1 ⌉ len\le\lfloor\frac{Max-Min+n-2}{n-1}\rfloor=\lceil\frac{Max-Min}{n-1}\rceil lenn1MaxMin+n2=n1MaxMin C + + C++ C++ 代码只使用不等式的前半段。

有了子区间的长度,数字就可以对应到子区间了。再次遍历 n u m s nums nums ,维护每个子区间的最大值 m a x max max ,最小值 m i n min min ,区间是否用到 u s e d used used

最后遍历所有子区间,维护答案,即为所求。

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        const int INF = 0x3f3f3f3f;
        struct Range{
            int min,max;
            bool used;
            Range () : min(INF) , max ( -INF) , used(false) {}
        };
        int n = nums.size();
        int Min = INF, Max = -INF;
        for(auto &x:nums){
            Min = Min<x?Min:x;
            Max = Max>x?Max:x;
        }
        if(nums.size()<2||Min==Max) return 0;
        vector<Range> r(n-1);
        int len = (Max - Min + n - 2) /(n-1);
        for(auto &x:nums){
            if( x == Min) continue;
            int i = (x - Min -1) / len;
            r[i].min = min(r[i].min,x);
            r[i].max = max(r[i].max,x);
            r[i].used = true;
        }
        int ans = 0 ;
        for(int i = 0,last = Min;i<n-1;i++){
            if(!r[i].used) continue;
            ans = max(ans,r[i].min - last);
            last = r[i].max;
        }
        return ans;
    }
};
  1. 时间复杂度 : O ( n ) O(n) O(n) n n n 是数字数量, 找出最大最小值,计算每个桶的最大最小值,遍历所有桶维护答案,总时间复杂度 O ( 3 × n ) O(3\times n) O(3×n) ,忽略常数时间复杂度 O ( n ) O(n) O(n)
  2. 空间复杂度 : O ( n ) O(n) O(n) n − 1 n-1 n1 个桶的空间复杂度 O ( n ) O(n) O(n)
AC

AC

致语
  • 理解思路很重要!
  • 欢迎读者在评论区留言,墨染看到就会回复的。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清墨韵染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值