[LeetCode] 719. Find K-th Smallest Pair Distance

The distance of a pair of integers a and b is defined as the absolute difference between a and b.

Given an integer array nums and an integer k, return the kth smallest distance among all the pairs nums[i] and nums[j] where 0 <= i < j < nums.length.

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.

Example 2:

Input: nums = [1,1,1], k = 2
Output: 0

Example 3:

Input: nums = [1,6,1], k = 3
Output: 5 

Constraints:

  • n == nums.length
  • 2 <= n <= 104
  • 0 <= nums[i] <= 106
  • 1 <= k <= n * (n - 1) / 2

找出第 k 小的距离对。

数对 (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。

来源:力扣(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

719. Find K-th Smallest Pair Distance

LeetCode 题目总结

posted @ 2021-02-13 07:39  CNoodle  阅读(119)  评论(0编辑  收藏  举报