Leetcode 719. Find K-th Smallest Pair Distance

Problem:

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.

Solution:

  这道题和Leetcode 774相比真是有过之而无不及,就算我看了标签是用Binary Search也不知道该如何解决。这道题和774有类似之处,首先这两道题都可以事先确定结果可能的范围,然后在这个范围内进行二分查找,对中间的数作为结果去验证是否满足条件,也是使用了逆向思维。首先对数组进行排序,我们知道第k个小的pair的距离必然在0到数组的极差之间,所以我们在这个范围内进行二分搜索,每次搜索都要计算在全部的pair中距离小于pivot的对数,如果小于pivot的pair数量太小,说明我们的pivot值小于真正的结果值,所以left+1,否则说明pivot过大,将right设置为pivot,在这里计算全部的pair中距离小于pivot的对数时还用了一个滑动窗口,用来在线性时间复杂度内计算小于pivot的pair的对数。因此次时间复杂度为O(nlogn+nlog W),W为极差。

Code:

 1 class Solution {
 2 public:
 3     int smallestDistancePair(vector<int>& nums, int k) {
 4         int m = nums.size();
 5         sort(nums.begin(),nums.end());
 6         int left = 0;
 7         int right = nums.back()-nums[0];
 8         while(left < right){
 9             int pivot = left+(right-left)/2;
10             int count = 0;
11             int start = 0;
12             for(int i = 0;i != m;++i){
13                 while(start < i && nums[i]-nums[start] > pivot)
14                     start++;
15                 count += (i-start);
16             }
17             if(count < k) left = pivot+1;
18             else right = pivot;
19         }
20         return left;
21     }
22 };

猜你喜欢

转载自www.cnblogs.com/haoweizh/p/10201312.html