719. Find K-th Smallest Pair Distance

Posted habibah-chang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了719. Find K-th Smallest Pair Distance相关的知识,希望对你有一定的参考价值。

问题:

求给定数组中两两元素之差,从小到大第k个差是多少

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.

  

解法1:

暴力求解法:

首先排序数组,然后两两遍历元素,求之差存入桶数组,差为桶数组的index,桶数组的value为差为index的pair个数。

然后从0~桶数组size去遍历桶数组,cout+=value累加>=k时,返回index

参考代码:

 1 class Solution {
 2 public:
 3     int smallestDistancePair(vector<int>& nums, int k) {
 4         sort(nums.begin(), nums.end());
 5         int bucket[nums.back()+1];
 6         memset(bucket, 0, sizeof(bucket));
 7         int cout=0;
 8         for(int i=0; i<nums.size(); i++){
 9             for(int j=i+1; j<nums.size(); j++){
10                 bucket[nums[j]-nums[i]]++;
11             }
12         }
13         for(int i=0; i<nums.back()+1; i++){
14             cout+=bucket[i];
15             if(cout>=k) return i;
16         }
17         return 0;
18     }
19 };

 

解法2:

二分查找,动态规划:

首先sort原数组,

查找要找的第k个差的值m是多少

l=最小差值0,r=最大差值nums.back()-nums[0]

每次计算到该m个差值,一共有多少cout个满足的两两元素对,

若个数cout>=k,那么应在 l~m-1 寻找新的m(第k个小的差)

??这里同时可能为最终的查找结束点,当前m=l=r被锁定,cout>=k,r=m-1使得r<l,退出循环。

若个数cout<k,那么应在 m+1~r 寻找新的m(第k个小的差)

 

其中,每次计算cout的话,应有以下计算方法:

遍历i:0~n,遍历j:i+1~n,求两个元素nums[i]和nums[j]的差(<=m):

??其中,每次递增 i ,又要重新遍历 j,复杂度太大,

由于每次要求的只是临界,i和j的差值<=m后的cout数(=j-i)

(注意??这里退出循环时j++不满足循环条件,因此满足条件的 j 应该-1,即cout数应该为 j-1-i),

我们每次递增 i 的时候,已经遍历到的 j 和 i 的差值一定是缩小了的,我们只需继续从当前的 j 开始递增,继续去找接下来的 j 就可以了。

 

参考代码:

 1 class Solution {
 2 public:
 3     int smallestDistancePair(vector<int>& nums, int k) {
 4         sort(nums.begin(), nums.end());
 5         int n=nums.size();
 6         int cout=0;
 7         int l=0, r=nums.back()-nums[0], m;
 8         while(l<=r){
 9             cout=0;
10             m=l+(r-l)/2;
11             int j=1;
12             for(int i=0; i<n; i++){//O(n) j不用重新从头开始遍历
13                 while((nums[j]-nums[i]<=m)&&j<n) j++;
14                 cout+=(j-1-i);
15             }
16             if(cout>=k){
17                 r=m-1;
18             }else{
19                 l=m+1;
20             }
21         }
22         return l;
23     }
24 };

 

以上是关于719. Find K-th Smallest Pair Distance的主要内容,如果未能解决你的问题,请参考以下文章

武大OJ 574. K-th smallest

786. K-th Smallest Prime Fraction

LWC 72: 786. K-th Smallest Prime Fraction

Leetcode: K-th Smallest in Lexicographical Order

[LeetCode] K-th Smallest in Lexicographical Order 字典顺序的第K小数字

The 15th Chinese Northeast L. k-th Smallest Common Substring(广义SAM,对节点字典序排序)