Leetcode719找到第K个最小的配对距离 Python Java C ++

问题描述

问题陈述如下- 给定一个整数数组,返回所有对中的第k个最小距离。一对(A,B)的距离定义为A和B之间的绝对差。

leetcode接受的解决方案是二进制搜索+前缀和方法。但是即使经过100次以上,我也无法弄清楚。

有人可以引导我吗?可能只是一个例子,可以帮助我弄清楚我们实际上是如何使用二进制搜索消除搜索间的?请帮我举个例子,因为互联网上有足够的描述性解释

解决方法

这是一个LeetCode硬标签的问题,您可以看到各种解决方案的说明here in this link

Python

class Solution:
    def smallestDistancePair(self,nums,k):
        def count(arr,val):
            res = 0
            for i in range(len(arr)):
                res += bisect.bisect_right(arr,arr[i] + val,lo=i) - i - 1
            return res

        nums.sort()
        lo = min(abs(nums[i] - nums[i + 1]) for i in range(len(nums) - 1))
        hi = abs(nums[0] - nums[~0])
        while lo < hi:
            mid = (lo + hi) // 2
            if count(nums,mid) < k:
                lo = mid + 1
            else:
                hi = mid
        return lo

Java

class Solution {
    private int upperBound(int[] nums,int lo,int hi,int key) {
        if (nums[hi] <= key)
            return hi + 1;
        while (lo < hi) {
            int mid = (lo + hi) / 2;
            if (key >= nums[mid])
                lo = mid + 1;
            else
                hi = mid;
        }
        return lo;
    }

    private int countPairs(int[] nums,int mid) {
        int length = nums.length;
        int res = 0;
        for (int i = 0; i < length; i++)
            res += upperBound(nums,i,length - 1,nums[i] + mid) - i - 1;
        return res;
    }

    public int smallestDistancePair(int[] nums,int k) {
        int length = nums.length;
        Arrays.sort(nums);
        int lo = nums[1] - nums[0];
        for (int i = 1; i < length - 1; i++)
            lo = Math.min(lo,nums[i + 1] - nums[i]);

        int hi = nums[length - 1] - nums[0];

        while (lo < hi) {
            int mid = (lo + hi) / 2;
            if (countPairs(nums,mid) < k)
                lo = mid + 1;
            else
                hi = mid;
        }
        return lo;
    }
}

C ++

#include <vector>
#include <algorithm>

static const struct Solution {
    static const int smallestDistancePair(
        const std::vector<int> &nums,const int k
    ) {
        std::vector<int> copy_nums = nums;
        std::sort(copy_nums.begin(),copy_nums.end());
        const int length = copy_nums.size();
        int lo = 0;
        int hi = 1e6;

        while (lo < hi) {
            const int mid = lo + (hi - lo) / 2;
            int count = 0;

            for (int i = 0,j = 0; i < length; i++) {
                while (j < length and copy_nums[j] - copy_nums[i] <= mid) {
                    j++;
                }

                count += j - i - 1;
            }

            if (count < k) {
                lo = mid + 1;

            } else {
                hi = mid;
            }
        }

        return lo;
    }
};