题目链接:https://leetcode-cn.com/problems/find-k-th-smallest-pair-distance/
找第k小就套二分
找第k小的“距离”,就对距离二分,最小为0,最大为排序后数组头尾元素之差。开心的写一个if(check(mid))先放着,具体怎么实现check()慢慢想。
由于要找第k小,所以思路是对每一个mid,找小于等于它的数对有多少组,如果 > k则应该缩小mid(以使更多数对差大于mid),所以主函数就写好了(check为真则 r = mid - 1, 为假则 l = mid + 1,由于 l > r 前最后一次变换的 l 肯定为真,所以最后返回 l 即可)
下面要想check函数,遍历数组,对每个元素找到比其刚好大mid的元素位置,二者之间的个数就是满足条件的个数,最后求和判断与k的关系即可
代码如下:
class Solution {
public:
bool check(vector<int> a, int k, int x) {
//printf("mid = %d\n", x);
int res = 0;
int index = 1;
for(int i = 0; i < a.size(); i++) {
int j = index;
while(j < a.size() && a[j] <= a[i] + x) {
j++;
}
//printf("out, j = %d\n", j);
res += j - i - 1;
index = j;
//printf("res = %d, index = %d\n", res, index);
}
//res >= k ? printf("Return True\n\n") : printf("Return False\n\n");
return res >= k;
}
int smallestDistancePair(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int l = 0, r = int(nums.back()) - nums[0];
while(l <= r) {
int mid = l + ((r - l) >> 1);
if(check(nums, k, mid)) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return l;
}
};