AlgoMaster Logo

Find K-th Smallest Pair Distance

hardUpdated September 21, 2026

Understanding the Problem

We have an array of integers, and we need to consider every possible pair (i, j) where i < j. For each pair, we compute the absolute difference |nums[i] - nums[j]|. Among all these distances, we want the k-th smallest one.

Two details shape the solution. First, the number of pairs is n*(n-1)/2, which reaches about 50 million when n = 10^4. Storing all those distances and sorting them is expensive. Second, many pairs can share the same distance, so we want the k-th value in the full sorted list of all pair distances counted with duplicates, not the k-th distinct distance.

Sorting the array first makes the distances easier to reason about. Once nums is sorted, the distance between two elements depends only on their positions in sorted order: nums[j] - nums[i] for i < j is always non-negative, so the absolute value disappears, and elements that are close in sorted order have smaller distances.

Key Constraints:

  • 2 <= n <= 10^4 → There are up to ~50 million pairs, so any approach that enumerates every pair does on the order of 10^8 operations. That is borderline, which motivates an approach that avoids enumerating pairs at all.
  • 0 <= nums[i] <= 10^6 → The maximum possible distance is 10^6. This bounds the search space when binary searching on the distance value, and it keeps every distance within a 32-bit integer.
  • 1 <= k <= n * (n - 1) / 2 → k is always valid, so there is no "k too large" edge case to handle.

Approach 1: Brute Force

Intuition

Do exactly what the problem says: compute the distance for every pair, collect all distances, sort them, and return the k-th one. With n up to 10^4 there are about 50 million pairs, so this is slow, but it establishes a correct baseline.

After sorting the input array, iterate over all pairs (i, j) with i < j. Because the array is sorted, the distance is nums[j] - nums[i] with no absolute value needed. Store all these distances in a list, sort the list, and return the element at index k-1.

Algorithm

  1. Sort nums.
  2. Create a list to store all pair distances.
  3. For each pair (i, j) where 0 <= i < j < n, compute nums[j] - nums[i] and add it to the list.
  4. Sort the distance list.
  5. Return the element at index k-1.

Visualization and Code

Loading animation...

This approach generates and sorts all pair distances, which is expensive in both time and space. The distances are bounded by 10^6, and the next approach uses that bound to replace the comparison sort with a counting step.

Approach 2: Bucket Sort

Intuition

The comparison sort over the distances costs O(n^2 log n), but the distances live in a bounded range. The maximum distance is max(nums) - min(nums), call it W. Create a frequency array of size W+1 where bucket[d] holds how many pairs have distance exactly d, then scan the buckets from 0 upward, accumulating counts until the running total reaches k.

This is a counting sort on the distances. It still generates all pairs in O(n^2), but it replaces the O(n^2 log n) sort with an O(W) scan.

Algorithm

  1. Sort nums.
  2. Compute W = nums[n-1] - nums[0].
  3. Create a frequency array bucket of size W+1, initialized to 0.
  4. For each pair (i, j) with i < j, increment bucket[nums[j] - nums[i]].
  5. Walk through bucket from index 0 upward. Subtract each bucket's count from k. When k drops to 0 or below, return the current index.

Visualization and Code

Loading animation...

This eliminates the comparison sort but still generates all n^2 pair distances, and W can be as large as 10^6. The next approach finds the k-th smallest distance without enumerating any pairs.

Approach 3: Binary Search on Answer + Two Pointers

Intuition

Instead of generating all distances, this approach answers a different question: for a given distance d, how many pairs have distance <= d? Define countPairs(d) as that count. As d increases, more pairs qualify, so countPairs is non-decreasing: if 10 pairs have distance <= 5, at least 10 pairs have distance <= 6. That monotonicity lets us binary search for the smallest d where countPairs(d) >= k, and that d is the k-th smallest distance.

Counting pairs with distance <= d on a sorted array uses two pointers. For each element nums[j], the earlier elements nums[i] with i < j that satisfy nums[j] - nums[i] <= d are those with nums[i] >= nums[j] - d. In sorted order these form a contiguous range ending at j-1, so finding its start with a left pointer that only moves forward costs O(n) total across all j.

Algorithm

  1. Sort nums.
  2. Set the binary search range: low = 0, high = nums[n-1] - nums[0].
  3. While low < high:
    • Compute mid = low + (high - low) / 2.
    • Count how many pairs have distance <= mid using two pointers.
    • If the count is >= k, set high = mid (the answer could be mid or smaller).
    • Otherwise, set low = mid + 1 (we need a larger distance).
  4. Return low.

For the counting step:

  • Use a left pointer starting at 0.
  • For each right pointer j from 0 to n-1:
    • Advance the left pointer while nums[j] - nums[left] > d.
    • The number of valid pairs ending at j is j - left.
    • Add this to the total count.

Visualization and Code

Loading animation...