問題鏈接
719. 找出第 K 小的數(shù)對距離
問題描述
數(shù)對 (a,b)
由整數(shù) a
和 b
組成拓提,其數(shù)對距離定義為 a
和 b
的絕對差值逼争。
給你一個整數(shù)數(shù)組 nums
和一個整數(shù) k
鸦概,數(shù)對由 nums[i]
和 nums[j]
組成且滿足 0 <= i < j < nums.length
赠堵。返回 所有數(shù)對距離中 第 k
小的數(shù)對距離。
提示:
- n == nums.length
- 2 <= n <= 104
- 0 <= nums[i] <= 106
- 1 <= k <= n * (n - 1) / 2
示例
示例1
輸入:nums = [1,3,1], k = 1
輸出:0
解釋:數(shù)對和對應的距離如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
距離第 1 小的數(shù)對是 (1,1) ,距離為 0 。
示例2
輸入:nums = [1,1,1], k = 2
輸出:0
示例3
輸入:nums = [1,6,1], k = 3
輸出:5
解題思路
看一下提示的范圍,就知道暴力破解直接沒戲~
這道題特铝,可以對數(shù)對距離的域值進行二分查找解題。
- 先對數(shù)組
nums
排序壹瘟; - 對數(shù)對距離的域值進行二分查找:
A. 初始left
為0鲫剿,right
為數(shù)組頭尾相減的絕對值,middle
為left
與right
和的一半稻轨;
B. 統(tǒng)計所有距離小于等于middle
的數(shù)對數(shù)量灵莲,記為count
;
C. 如果count
大于等于k
殴俱,right = middle - 1
政冻;反之,left = middle + 1
线欲;
D. 如果left
小于等于right
明场,繼續(xù)以上操作; - 當
left
大于right
時李丰,返回結(jié)果left
苦锨。
代碼示例(JAVA)
class Solution {
public int smallestDistancePair(int[] nums, int k) {
// 先進行排序
Arrays.sort(nums);
// 值域二分找k
int length = nums.length;
int left = 0, right = nums[length - 1] - nums[0];
while (left <= right) {
int middle = (right + left) / 2;
int count = countPair(nums, middle);
if (count >= k) {
right = middle - 1 ;
} else {
left = middle + 1;
}
}
return left;
}
// 統(tǒng)計數(shù)對
public int countPair(int[] nums, int value) {
int count = 0;
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] - nums[i] <= value) {
count++;
} else {
break;
}
}
}
return count;
}
}
執(zhí)行結(jié)果