Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pair (A, B) is defined as the absolute difference between A and B.
Example 1:
Input: nums = [1,3,1] k = 1 Output: 0 Explanation: Here are all the pairs: (1,3) -> 2 (1,1) -> 0 (3,1) -> 2 Then the 1st smallest distance pair is (1,1), and its distance is 0.
Note:
2 <= len(nums) <= 10000
.0 <= nums[i] < 1000000
.1 <= k <= len(nums) * (len(nums) - 1) / 2
.
找出第 k 小的距离对。
给定一个整数数组,返回所有数对之间的第 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。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-k-th-smallest-pair-distance
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我这里提供一个速度很慢的二分法思路,日后又优化我再更新。暴力解O(n^2)找出所有的pair然后再用最小堆排序的方法是会超时的。
按照题目例子的解释,我们要找的是第 K 小的距离,那么如果我们能把每两个数字之间的距离先做到有序的话,会对于找这个目标值很有帮助。所以我们先把input数组排序,然后才能使用二分法。排序结束之后,pair的最小值low是0,pair的最大值high是 nums[last] - nums[0]。差值的范围也就介于这两者之间,中间值我们记为mid = low + (high - low) / 2。
此时我们用另一个helper函数去计算input数组中到底有多少对pair之间的差值是小于mid的,如果不足K个,说明要找的那个差值还在右侧,low = mid + 1;如果超过K个,说明要找的那个差值在左侧,high = mid。
时间O(logn * n^2) = O(n^2logn)
空间O(n)
Java实现
class Solution { public int smallestDistancePair(int[] nums, int k) { int n = nums.length; Arrays.sort(nums); // minimum absolute differece int low = 0; int high = nums[n - 1] - nums[0]; while (low < high) { int mid = low + (high - low) / 2; if (helper(nums, mid) < k) { low = mid + 1; } else { high = mid; } } return low; } private int helper(int[] nums, int mid) { int n = nums.length; int res = 0; for (int i = 0; i < n; i++) { int j = i; while (j < n && nums[j] - nums[i] <= mid) { j++; } res += j - i - 1; } return res; } }
相关题目
373. Find K Pairs with Smallest Sums
378. Kth Smallest Element in a Sorted Matrix