码迷,mamicode.com
首页 > 其他好文 > 详细

719. Find K-th Smallest Pair Distance

时间:2020-05-04 15:42:43      阅读:48      评论:0      收藏:0      [点我收藏+]

标签:被锁   不用   pre   back   tor   not   i++   二分   nat   

问题:

求给定数组中两两元素之差,从小到大第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

标签:被锁   不用   pre   back   tor   not   i++   二分   nat   

原文地址:https://www.cnblogs.com/habibah-chang/p/12826490.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!