给定一个整数数组,返回所有数对之间的第 k 个最小距离。一对 (A, B) 的距离被定义为 A 和 B 之间的绝对差值。
示例 1:
输入:
nums = [1,3,1]
k = 1
输出:0
解释:
所有数对如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
因此第 1 个最小距离的数对是 (1,1),它们之间的距离为 0。
提示:
2 <= len(nums) <= 10000.
0 <= nums[i] < 1000000.
1 <= k <= len(nums) * (len(nums) - 1) / 2.
思路:两次二分,第一次二分答案,第二次二分这个答案是第几小的距离对。
class Solution {
public int smallestDistancePair(int[] nums, int k) {
Arrays.parallelSort(nums);
int[] d=new int[nums.length-1];
for(int i=1;i<nums.length;i++)
d[i-1]=nums[i]-nums[i-1];
int[] sum=new int[d.length];
sum[0]=d[0];
for(int i=1;i<d.length;i++)
sum[i]=sum[i-1]+d[i];
int ans=0;
int l=0,r=sum[d.length-1];
while(l<=r) {
int mid=l+(r-l)/2;
if(check(sum,k,mid)) {
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
return ans;
}
private boolean check(int[] sum,int k,int d) {
int num=0;
for(int i=0;i<sum.length;i++) {
if(sum[i]>d) {
int l=0,r=i-1,p=i;
while(l<=r) {
int mid=(l+r)/2;
if(sum[i]-sum[mid]<=d) {
p=mid;
r=mid-1;
}
else
l=mid+1;
}
num+=i-p;
}
else
num+=i+1;
}
return num>=k;
}
}