Leetcode 719. Find K-th Smallest Pair Distance
阿新 • • 發佈:2018-12-31
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:
2 <= len(nums) <= 10000
.0 <= nums[i] < 1000000
.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 intpivot = 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 };