来源:力扣(LeetCode)
描述:
数对 (a,b)
由整数 a
和 b
组成,其数对距离定义为 a
和 b
的绝对差值。
给你一个整数数组 nums
和一个整数 k
,数对由 nums[i]
和 nums[j]
组成且满足 0 <= i < j < nums.length
。返回 所有数对距离中 第 k
小的数对距离。
示例 1:
输入:nums = [1,3,1], k = 1
输出:0
解释:数对和对应的距离如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
距离第 1 小的数对是 (1,1) ,距离为 0 。
示例 2:
输入:nums = [1,1,1], k = 2
输出:0
示例 3:
输入:nums = [1,6,1], k = 3
输出:5
提示:
- n == nums.length
- 2 <= n <= 104
- 0 <= nums[i] <= 106
- 1 <= k <= n * (n - 1) / 2
方法一:排序 + 二分查找
代码:
class Solution {
public:
int smallestDistancePair(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int n = nums.size(), left = 0, right = nums.back() - nums.front();
while (left <= right) {
int mid = (left + right) / 2;
int cnt = 0;
for (int j = 0; j < n; j++) {
int i = lower_bound(nums.begin(), nums.begin() + j, nums[j] - mid) - nums.begin();
cnt += j - i;
}
if (cnt >= k) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
};
执行用时:32 ms, 在所有 C++ 提交中击败了12.52%的用户
内存消耗:9.9 MB, 在所有 C++ 提交中击败了13.77%的用户
方法二:排序 + 二分查找 + 双指针
代码:
class Solution {
public:
int smallestDistancePair(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int n = nums.size(), left = 0, right = nums.back() - nums.front();
while (left <= right) {
int mid = (left + right) / 2;
int cnt = 0;
for (int i = 0, j = 0; j < n; j++) {
while (nums[j] - nums[i] > mid) {
i++;
}
cnt += j - i;
}
if (cnt >= k) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
};
执行用时:12 ms, 在所有 C++ 提交中击败了66.55%的用户
内存消耗:9.7 MB, 在所有 C++ 提交中击败了99.11%的用户
author:LeetCode-Solution