Search lands in PR-5.1 (Pagefind).

How-to Intermediate

Chapter 4 Updated

K Closest Elements to X

Max-heap of size K on |value − x|; evict the farthest.

  • Full 6m
  • Revision
  • Flow

Problem Statement

Given an array of integers arr, an integer k, and a target value x, return the k values in arr that are closest to x by absolute difference. Results may be returned in any order (unless the problem asks for sorted).

Input

An integer array arr, target value x, and the count k.

Example input
arr = [1, 2, 3, 4, 5]
k   = 4
x   = 3

Output

The k closest values.

Expected output
[1, 2, 3, 4]
 
// distances from 3:
// 1→2  2→1  3→0  4→1  5→2
// smallest 4 distances: 0, 1, 1, 2 → values 3, 2, 4, 1

Constraints

  • 1 ≤ k ≤ arr.length ≤ 10⁴
  • -10⁴ ≤ arr[i], x ≤ 10⁴

Intuition

“Closest to X” is just “smallest by |x − value|”. We want the K smallest distances — classic max-heap-of-size-K. Push (distance, value) tuples and keep the heap capped at K; whatever remains is our answer.

Walkthrough — arr=[1,2,3,4,5], k=4, x=3
num  dist  heap after push           heap after evict (size > 4)
 1    2    [(2,1)]                   —
 2    1    [(2,1),(1,2)]             —
 3    0    [(2,1),(1,2),(0,3)]       —
 4    1    [(2,1),(1,2),(0,3),(1,4)] —
 5    2    push → (2,1) & (2,5) tie  pop max → {(1,2),(0,3),(1,4),(2,?)}
 
result values (sorted): [1, 2, 3, 4] ✓

Solution

k_closest_elements.py
import heapq
 
def findClosestElements(arr: list[int], k: int, x: int) -> list[int]:
    max_heap: list[tuple[int, int]] = []    # (-distance, value)
    for num in arr:
        dist = abs(num - x)
        heapq.heappush(max_heap, (-dist, num))
        if len(max_heap) > k:
            heapq.heappop(max_heap)         # evict the farthest
    return sorted(v for _, v in max_heap)

Complexity

MetricValueReason
TimeO(n log k)Same structure as any Top-K. Final sort of heap contents adds O(k log k), dominated by the first term.
SpaceO(k)Heap capped at K. Output list is also K elements.

Edge Case Thinking

ScenarioHandling
Ties in distanceLeetCode 658 requires the smaller value to win ties. Use (-dist, -value) in the max-heap so smaller values survive eviction.
x outside array rangeAlgorithm still works — nothing assumes x is in-bounds.
k == len(arr)Entire array is the answer; heap grows to full size with no evictions.
DuplicatesEach occurrence treated independently — duplicates near x are all valid answers.
Empty array or k == 0Return [].

Comments

Comments are disabled in this environment. Set PUBLIC_GISCUS_REPO, PUBLIC_GISCUS_REPO_ID, and PUBLIC_GISCUS_CATEGORY_ID to enable.