Kth Smallest Pairwise Difference

Last Updated : 26 Jun, 2026

Given an integer array arr[] of size n and an integer k, consider the absolute difference of arr[i] and arr[j] for every pair of indices i != j. Find the kth smallest value among all these pairwise differences.

Examples: 

Input: arr[] = [1, 2, 3, 4], k = 3
Output: 1
Explanation: The pairwise differences are [1, 2, 3, 1, 2, 1]. Sorted, they become [1, 1, 1, 2, 2, 3] - the 3rd smallest is 1.

Input: arr[] = [10, 10, 10, 10], k = 6
Output: 0
Explanation: Every pair of elements is identical, so all 6 pairwise differences are 0. Hence, the 6th smallest is 0.

Try It Yourself
redirect icon

[Naive Approach] Using Pairwise Difference Generation - O((n * n) log n) Time and O(n * n) Space

The idea is to explicitly generate every pairwise absolute difference abs(arr[i] - arr[j]) for all i < j, store them all in a list, sort this list, and simply return the kth element. This directly mirrors the problem statement but requires storing and sorting all n*(n-1)/2 differences, making it slow for large arrays.

Step by Step Explanation:

  • Generate every pairwise difference abs(arr[i] - arr[j]) for all valid index pairs i < j.
  • Store all these differences in a list.
  • Sort the list of differences in ascending order.
  • Return the element at index k-1 (the kth smallest).
C++
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

int kthSmallest(vector<int> &arr, int k) {
    vector<int> diffs;
    int n = arr.size();

    // Generate every pairwise difference
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            diffs.push_back(abs(arr[i] - arr[j]));
        }
    }

    sort(diffs.begin(), diffs.end());
    return diffs[k - 1];
}

int main() {
    vector<int> arr = {1, 2, 3, 4};
    int k = 3;

    cout << kthSmallest(arr, k) << endl;
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Collections;

class GFG {
    static int kthSmallest(int[] arr, int k) {
        ArrayList<Integer> diffs = new ArrayList<>();
        int n = arr.length;

        // Generate every pairwise difference
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                diffs.add(Math.abs(arr[i] - arr[j]));
            }
        }

        Collections.sort(diffs);
        return diffs.get(k - 1);
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        int k = 3;

        System.out.println(kthSmallest(arr, k));
    }
}
Python
def kthSmallest(arr, k):
    diffs = []
    n = len(arr)

    # Generate every pairwise difference
    for i in range(n):
        for j in range(i + 1, n):
            diffs.append(abs(arr[i] - arr[j]))

    diffs.sort()
    return diffs[k - 1]

arr = [1, 2, 3, 4]
k = 3

print(kthSmallest(arr, k))
C#
using System;
using System.Collections.Generic;

class GFG {
    static int kthSmallest(int[] arr, int k) {
        List<int> diffs = new List<int>();
        int n = arr.Length;

        // Generate every pairwise difference
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                diffs.Add(Math.Abs(arr[i] - arr[j]));
            }
        }

        diffs.Sort();
        return diffs[k - 1];
    }

    static void Main() {
        int[] arr = { 1, 2, 3, 4 };
        int k = 3;

        Console.WriteLine(kthSmallest(arr, k));
    }
}
JavaScript
function kthSmallest(arr, k) {
    const diffs = [];
    const n = arr.length;

    // Generate every pairwise difference
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            diffs.push(Math.abs(arr[i] - arr[j]));
        }
    }

    diffs.sort((a, b) => a - b);
    return diffs[k - 1];
}

// Driver Code
const arr = [1, 2, 3, 4];
const k = 3;

console.log(kthSmallest(arr, k));

Output
1

[Better Approach] Using Min-Heap - O((n + k) log n) Time and O(n) Space

The idea is to sort the array. After sorting, for each index i, the differences arr[j] - arr[i] (for j > i) increase as j grows - so each i generates its own naturally sorted sequence of candidates. Using a min-heap to always pop the smallest pending difference across all these sequences lets us extract differences in fully sorted order, stopping as soon as we've popped the kth one.

Step by Step Implementation:

  • Sort the array.
  • Push (arr[i+1] - arr[i], i, i+1) into a min-heap for every i from 0 to n-2.
  • Pop the smallest difference from the heap, k times.
  • After each pop (diff, i, j), if j+1 < n, push (arr[j+1] - arr[i], i, j+1) as the next candidate for that same i.
  • The value popped on the kth time is the answer.
C++
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

int kthSmallest(vector<int> &arr, int k) {
    sort(arr.begin(), arr.end());
    int n = arr.size();

    // min-heap of {difference, i, j}
    priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> heap;

    for (int i = 0; i < n - 1; i++) {
        heap.push({arr[i + 1] - arr[i], i, i + 1});
    }

    int diff = -1;
    for (int count = 0; count < k; count++) {
        vector<int> top = heap.top();
        heap.pop();
        diff = top[0];
        int i = top[1], j = top[2];

        if (j + 1 < n) {
            heap.push({arr[j + 1] - arr[i], i, j + 1});
        }
    }

    return diff;
}

int main() {
    vector<int> arr = {1, 2, 3, 4};
    int k = 3;

    cout << kthSmallest(arr, k) << endl;
    return 0;
}
Java
import java.util.Arrays;
import java.util.PriorityQueue;

class GFG {
    static int kthSmallest(int[] arr, int k) {
        Arrays.sort(arr);
        int n = arr.length;

        // min-heap of {difference, i, j}
        PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[0] - b[0]);

        for (int i = 0; i < n - 1; i++) {
            heap.add(new int[]{arr[i + 1] - arr[i], i, i + 1});
        }

        int diff = -1;
        for (int count = 0; count < k; count++) {
            int[] top = heap.poll();
            diff = top[0];
            int i = top[1], j = top[2];

            if (j + 1 < n) {
                heap.add(new int[]{arr[j + 1] - arr[i], i, j + 1});
            }
        }

        return diff;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        int k = 3;

        System.out.println(kthSmallest(arr, k));
    }
}
Python
import heapq

def kthSmallest(arr, k):
    arr.sort()
    n = len(arr)

    # min-heap of (difference, i, j)
    heap = []
    for i in range(n - 1):
        heapq.heappush(heap, (arr[i + 1] - arr[i], i, i + 1))

    diff = -1
    for _ in range(k):
        diff, i, j = heapq.heappop(heap)
        if j + 1 < n:
            heapq.heappush(heap, (arr[j + 1] - arr[i], i, j + 1))

    return diff

arr = [1, 2, 3, 4]
k = 3

print(kthSmallest(arr, k))
C#
using System;
using System.Collections.Generic;

class GFG {
    static int kthSmallest(int[] arr, int k) {
        Array.Sort(arr);
        int n = arr.Length;

        // min-heap of (difference, i, j) using SortedSet as a substitute priority queue
        SortedSet<(int diff, int i, int j)> heap = new SortedSet<(int, int, int)>();

        for (int i = 0; i < n - 1; i++) {
            heap.Add((arr[i + 1] - arr[i], i, i + 1));
        }

        int diff = -1;
        for (int count = 0; count < k; count++) {
            var top = heap.Min;
            heap.Remove(top);
            diff = top.diff;
            int i = top.i, j = top.j;

            if (j + 1 < n) {
                heap.Add((arr[j + 1] - arr[i], i, j + 1));
            }
        }

        return diff;
    }

    static void Main() {
        int[] arr = { 1, 2, 3, 4 };
        int k = 3;

        Console.WriteLine(kthSmallest(arr, k));
    }
}
JavaScript
class MinHeap {
    constructor() {
        this.heap = [];
    }

    push(item) {
        this.heap.push(item);
        let i = this.heap.length - 1;
        while (i > 0) {
            const parent = Math.floor((i - 1) / 2);
            if (this.heap[parent][0] <= this.heap[i][0]) break;
            [this.heap[parent], this.heap[i]] = [this.heap[i], this.heap[parent]];
            i = parent;
        }
    }

    pop() {
        const top = this.heap[0];
        const last = this.heap.pop();
        if (this.heap.length > 0) {
            this.heap[0] = last;
            let i = 0;
            while (true) {
                let left = 2 * i + 1, right = 2 * i + 2, smallest = i;
                if (left < this.heap.length && this.heap[left][0] < this.heap[smallest][0]) smallest = left;
                if (right < this.heap.length && this.heap[right][0] < this.heap[smallest][0]) smallest = right;
                if (smallest === i) break;
                [this.heap[i], this.heap[smallest]] = [this.heap[smallest], this.heap[i]];
                i = smallest;
            }
        }
        return top;
    }
}

function kthSmallest(arr, k) {
    arr.sort((a, b) => a - b);
    const n = arr.length;

    // min-heap of [difference, i, j]
    const heap = new MinHeap();
    for (let i = 0; i < n - 1; i++) {
        heap.push([arr[i + 1] - arr[i], i, i + 1]);
    }

    let diff = -1;
    for (let count = 0; count < k; count++) {
        const top = heap.pop();
        diff = top[0];
        const i = top[1], j = top[2];

        if (j + 1 < n) {
            heap.push([arr[j + 1] - arr[i], i, j + 1]);
        }
    }

    return diff;
}

// Driver Code
const arr = [1, 2, 3, 4];
const k = 3;

console.log(kthSmallest(arr, k));

Output
1

[Expected Approach] Using Binary Search on Answer - O(n log n) Time and O(1) Space

The idea is to binary search on the answer itself - the value of the kth smallest difference - rather than generating every pairwise difference explicitly. For a candidate difference mid, we can count how many pairs have difference â‰Ī mid in O(n) using two pointers on the sorted array. If that count is at least k, the answer is mid or smaller; otherwise it must be larger. This narrows the search space by half each time instead of enumerating all pairs.

Step by Step Implementation:

  • Sort the array.
  • Binary search on the difference value, between 0 and max(arr) - min(arr).
  • For each candidate mid, use two pointers to count how many pairs have difference â‰Ī mid.
  • If that count is â‰Ĩ k, move the search range down (the answer is â‰Ī mid); otherwise move it up.
  • Once the search range narrows to a single value, that value is the kth smallest difference.
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int kthSmallest(vector<int> &arr, int k) {
    sort(arr.begin(), arr.end());
    int n = arr.size();
    int lo = 0, hi = arr[n - 1] - arr[0];

    while (lo < hi) {
        int mid = lo + (hi - lo) / 2;

        // Count pairs with difference <= mid using two pointers
        long long count = 0;
        int j = 0;
        for (int i = 0; i < n; i++) {
            while (j < n && arr[j] - arr[i] <= mid) j++;
            count += (j - i - 1);
        }

        if (count >= k) hi = mid;
        else lo = mid + 1;
    }

    return lo;
}

int main() {
    vector<int> arr = {1, 2, 3, 4};
    int k = 3;

    cout << kthSmallest(arr, k) << endl;
    return 0;
}
Java
import java.util.Arrays;

class GFG {
    static int kthSmallest(int[] arr, int k) {
        Arrays.sort(arr);
        int n = arr.length;
        int lo = 0, hi = arr[n - 1] - arr[0];

        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;

            // Count pairs with difference <= mid using two pointers
            long count = 0;
            int j = 0;
            for (int i = 0; i < n; i++) {
                while (j < n && arr[j] - arr[i] <= mid) j++;
                count += (j - i - 1);
            }

            if (count >= k) hi = mid;
            else lo = mid + 1;
        }

        return lo;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        int k = 3;

        System.out.println(kthSmallest(arr, k));
    }
}
Python
def kthSmallest(arr, k):
    arr.sort()
    n = len(arr)
    lo, hi = 0, arr[n - 1] - arr[0]

    while lo < hi:
        mid = lo + (hi - lo) // 2

        # Count pairs with difference <= mid using two pointers
        count = 0
        j = 0
        for i in range(n):
            while j < n and arr[j] - arr[i] <= mid:
                j += 1
            count += (j - i - 1)

        if count >= k:
            hi = mid
        else:
            lo = mid + 1

    return lo

arr = [1, 2, 3, 4]
k = 3

print(kthSmallest(arr, k))
C#
using System;

class GFG {
    static int kthSmallest(int[] arr, int k) {
        Array.Sort(arr);
        int n = arr.Length;
        int lo = 0, hi = arr[n - 1] - arr[0];

        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;

            // Count pairs with difference <= mid using two pointers
            long count = 0;
            int j = 0;
            for (int i = 0; i < n; i++) {
                while (j < n && arr[j] - arr[i] <= mid) j++;
                count += (j - i - 1);
            }

            if (count >= k) hi = mid;
            else lo = mid + 1;
        }

        return lo;
    }

    static void Main() {
        int[] arr = { 1, 2, 3, 4 };
        int k = 3;

        Console.WriteLine(kthSmallest(arr, k));
    }
}
JavaScript
function kthSmallest(arr, k) {
    arr.sort((a, b) => a - b);
    const n = arr.length;
    let lo = 0, hi = arr[n - 1] - arr[0];

    while (lo < hi) {
        const mid = lo + Math.floor((hi - lo) / 2);

        // Count pairs with difference <= mid using two pointers
        let count = 0;
        let j = 0;
        for (let i = 0; i < n; i++) {
            while (j < n && arr[j] - arr[i] <= mid) j++;
            count += (j - i - 1);
        }

        if (count >= k) hi = mid;
        else lo = mid + 1;
    }

    return lo;
}

// Driver Code
const arr = [1, 2, 3, 4];
const k = 3;

console.log(kthSmallest(arr, k));

Output
1
Comment