LC719

719. 找出第 K 小的数对距离

719. 找出第 K 小的数对距离 - 力扣(LeetCode)

数对 (a,b) 由整数 a 和 b 组成,其数对距离定义为 a 和 b 的绝对差值。

给你一个整数数组 nums 和一个整数 k ,数对由 nums[i] 和 nums[j] 组成且满足 0 <= i < j < nums.length 。返回 所有数对距离中 第 k 小的数对距离。

我们直接二分答案,答案最小取 0,最大取 mx - mn。

首先将 nums 排序 ,然后 check 的逻辑如下 :

对于第 k + 1 小,第 k + 2 小,… , 第 n 小的元素 x 一定满足 <= x 的元素 >= k 个 ;

前 k 小的元素 x 不一定满足 <= x 的元素 < k 个,因为可能存在很多重复元素。

class Solution {
public:
    int smallestDistancePair(vector<int>& a, int k) {
        sort(a.begin(), a.end());
        /*
            除了前 k 小的数, 第 k + 1 小的数, 第 k + 2 小的数, ... , 第 n 小的数都满足以下性质 :
            <= 它的数 >= k 个
            (注意前 k 小的数, <= 它的数不一定 < k 个, 因为存在相等的情况)
        */
        // 第 1 小, 2 小 ..., k 小的数 x 满足所有数对之差 <=x 的数量 < k
        auto check = [&] (int mid) -> bool {
            int res = 0;
            deque<int> q;
            for(auto &x : a){
                q.push_back(x);
                while(q.front() < x - mid) q.pop_front();
                res += q.size() - 1;
            }
            return res >= k;
        };
        
        int l = 0, r = a.back() - a[0];
        while(l < r){
            int mid = l + r >> 1;
            if(check(mid)) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};

/*
    共有 n * (n - 1) / 2 对数对距离, 让求第 k 小的距离 res
    二分 res, l = 0, r = mx - mn
    check : 
        计算所有距离 <= mid 的数对数量 cnt 
    首先呢, 对于前 k 小的数对距离 x, <= x 的数 >= k 个
    二分左侧最大的那个
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值