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 个
二分左侧最大的那个
*/