1. 程式人生 > >Leetcode 719. Find K-th Smallest Pair Distance

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 };