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


    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:

    1. 2 <= len(nums) <= 10000.
    2. 0 <= nums[i] < 1000000.
    3. 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

    719. Find K-th Smallest Pair Distance

    LeetCode 题目总结

  • 相关阅读:
    shell字符串截取
    QT,QT SDK, QT Creator 区别
    linux -- 扩容 /home 空间( xfs文件系统分区扩容指定挂载点)
    条件变量与互斥量
    越努力越幸运--2018年7月22日周记
    越努力越幸运--动态数组vector
    越努力越幸运--3-日常bug修复
    越努力越幸运--2-LD_PRELOAD, fork ,僵尸进程
    越努力越幸运--1
    makefile--回顾基础篇
  • 原文地址:https://www.cnblogs.com/cnoodle/p/14399741.html
Copyright © 2020-2023  润新知