Find K-th Smallest Pair Distance
Given an integer array, return the k-th smallestdistanceamong all the pairs. The distance of a pair (A, B) is defined as the absolute difference between A and B.
Example 1:
Solution
Approach #1: Heap
Intuition and Algorithm
Sort the points. For every point with indexi
, the pairs with indexes(i, j)
[by order of distance] are(i, i+1), (i, i+2), ..., (i, N-1)
.
Let's keep a heap of pairs, initiallyheap = [(i, i+1) for all i]
, and ordered by distance (the distance of(i, j)
isnums[j] - nums[i]
.) Whenever we use a pair(i, x)
from our heap, we will add(i, x+1)
to our heap when appropriate.
Complexity Analysis
Time Complexity:O((k+N)logN)O((k+N)logN), whereNNis the length of
nums
. Ask=O(N2)k=O(N2), this isO(N2logN)O(N2logN)in the worst case. The complexity added by our heap operations is eitherO((k+N)logN)O((k+N)logN)in the Java solution, orO(klogN+N)O(klogN+N)in the Python solution because theheapq.heapify
operation is linear time. Additionally, we addO(NlogN)O(NlogN)complexity due to sorting.Space Complexity:O(N)O(N), the space used to store our
heap
of at mostN-1
elements.
Approach #2: Binary Search + Prefix Sum
Intuition
Let's binary search for the answer. It's definitely in the range[0, W]
, whereW = max(nums) - min(nums)]
.
Letpossible(guess)
be true if and only if there arek
or more pairs with distance less than or equal toguess
. We will focus on evaluating ourpossible
function quickly.
Algorithm
Letprefix[v]
be the number of points innums
less than or equal tov
. Also, letmultiplicity[j]
be the number of pointsi
withi < j and nums[i] == nums[j]
. We can record both of these with a simple linear scan.
Now, for every pointi
, the number of pointsj
withi < j
andnums[j] - nums[i] <= guess
isprefix[x+guess] - prefix[x] + (count[i] - multiplicity[i])
, wherecount[i]
is the number of ocurrences ofnums[i]
innums
. The sum of this over alli
is the number of pairs with distance<= guess
.
Finally, because the sum ofcount[i] - multiplicity[i]
is the same as the sum ofmultiplicity[i]
, we could just replace that term withmultiplicity[i]
without affecting the answer. (Actually, the sum of multiplicities in total will be a constant used in the answer, so we could precalculate it if we wanted.)
In our Java solution, we computedpossible = count >= k
directly in the binary search instead of using a helper function.
Complexity Analysis
Time Complexity:O(W+NlogW+NlogN)O(W+NlogW+NlogN), whereNNis the length of
nums
, andWWis equal tonums[nums.length - 1] - nums[0]
. We doO(W)O(W)work to calculateprefix
initially. ThelogWlogWfactor comes from our binary search, and we doO(N)O(N)work inside our call topossible
(or to calculatecount
in Java). The finalO(NlogN)O(NlogN)factor comes from sorting.Space Complexity:O(N+W)O(N+W), the space used to store
multiplicity
andprefix
.
Approach #3: Binary Search + Sliding Window
Intuition
As inApproach #2, let's binary search for the answer, and we will focus on evaluating ourpossible
function quickly.
Algorithm
We will use a sliding window approach to count the number of pairs with distance<=
guess.
For every possibleright
, we maintain the loop invariant:left
is the smallest value such thatnums[right] - nums[left] <= guess
. Then, the number of pairs withright
as it's right-most endpoint isright - left
, and we add all of these up.
Complexity Analysis
Time Complexity:O(NlogW+NlogN)O(NlogW+NlogN), whereNNis the length of
nums
, andWWis equal tonums[nums.length - 1] - nums[0]
. ThelogWlogWfactor comes from our binary search, and we doO(N)O(N)work inside our call topossible
(or to calculatecount
in Java). The finalO(NlogN)O(NlogN)factor comes from sorting.Space Complexity:O(1)O(1). No additional space is used except for integer variables.
Last updated