LeetCode - 719. Find K-th Smallest Pair Distance 暴力 | 二分

发布于 2024-08-29 10:21:10 字数 3681 浏览 10 评论 0

题目

解析

第一种方法的思想:

  • 先将 nums 数组排序,然后暴力枚举所有的 distance (也就是 len * (len - 1 ) / 2 种),算出每一种 distance 出现的频率;
  • 然后利用类似桶排序的过程,每个频率看做一个桶,我们从小频率到大频率遍历,每次累加频率到一个 count 值,如果这个 count>=k ,即说明这个就是第 k 小的距离对了;

例子:

import java.io.*;
import java.util.*;

class Solution {

    // find K-th Smallest Pair Distance
    public int smallestDistancePair(int[] nums, int k) {
        Arrays.sort(nums);
        int n = nums.length;
        int[] freqs = new int[nums[n-1] + 1]; //注意 nums[i]可能为 0,所以要+1
        for(int i = 0; i < n; i++){ 
            for(int j = i + 1; j < n; j++){ 
                freqs[nums[j] - nums[i]]++;
            }
        }
        int cnt = 0;
        for(int d = 0; d < freqs.length; d++){ 
            cnt += freqs[d];
            if(cnt >= k)
                return d;
        }
        return 0;
    } 

    public static void main(String[] args){
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        PrintStream out = System.out;
        int[] nums = {1,3,1};
        int k = 1;
        out.println(new Solution().
            smallestDistancePair(nums, k)
        );
    }
}

这题更快的方法是用 二分+类似 DP 来解:

  • 也是需要先对 nums 数组排序,然后我们需要在最大距离值和最小距离值中找到一个值 key ,使得恰好它前面有 kpairs 他们的 distance <= key
  • 而我们需要找的恰好是最小的那样的 key ,所以需要利用二分查找的找到第一个 >=key 的写法,具体可以看 这篇博客
  • 这里每次二分里面我们需要去遍历数组( i ),看似每次需要用另一个索引 j 来逐个统计这种 pairdistance 是否 <=mid ,但是这个过程是一个递增的顺序,也就是说我们已经对数组排序了,然后有点类似两个指针不断往后推动的情况,也就是说原本需要 O(N^2) 的时间复杂度可以降低到 2 * O(N) ,所以总的时间复杂度是 O( 2 * N * log(N))

例子: 当二分寻找距离 <=3pair 数。

import java.io.*;
import java.util.*;

class Solution {

    // find K-th Smallest Pair Distance
    public int smallestDistancePair(int[] nums, int k) {
        Arrays.sort(nums);
        int n = nums.length;
        int L = 0;
        int R = nums[n-1] - nums[0];
        while(L <= R){ 
            int mid = L + (R - L) / 2;
            int count = 0;
            int j = 0;
            for(int i = 0; i < n; i++){
                while(j < n && nums[j] - nums[i] <= mid) j++;
                count += j - i - 1; // j not in it,  [i, i+1]、[i, i+2]....[i, j-1]'s dist <= m
            }
            if(count >= k) // 因为需要寻找第一个>=key 的, 所以不能当 count == k 的时候返回
                R = mid - 1;
            else           // 没有这么多对数的 dist <= m, 需要增加
                L = mid + 1; 
        }
        return L; // 返回第一个>=key 的
    } 

    public static void main(String[] args){
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        PrintStream out = System.out;
        int[] nums = {1,3,1};
        int k = 1;
        out.println(new Solution().
            smallestDistancePair(nums, k)
        );
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

瘫痪情歌

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

我们的影子

文章 0 评论 0

素年丶

文章 0 评论 0

南笙

文章 0 评论 0

18215568913

文章 0 评论 0

qq_xk7Ean

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文