Search lands in PR-5.1 (Pagefind).

How-to Intermediate

Chapter 3 Updated

Sort a Nearly Sorted Array

Min-heap of size k+1 slides the window; the root is always the next smallest.

  • Full 6m
  • Revision
  • Flow

Problem Statement

An array is nearly sorted (or K-sorted): each element is at most k positions away from where it would be in the fully-sorted array. Sort it efficiently — faster than a generic O(n log n) sort when k is small.

Input

An integer array arr that is K-sorted, and the window size k.

Example input
arr = [6, 5, 3, 2, 8, 10, 9]
k   = 3

Output

The fully sorted array.

Expected output
[2, 3, 5, 6, 8, 9, 10]

Constraints

  • 1 ≤ k < arr.length ≤ 10⁵
  • Every element in arr is within k positions of its sorted location.

Intuition

Since an element can be at most K positions away, the smallest remaining element must be within the next k+1 positions. Seed a min-heap with the first k+1 elements. The root is guaranteed to be the smallest. Pop it (it’s done), push the next incoming element, repeat. We never look further ahead than k+1 elements — that’s the whole window we need.

Walkthrough — arr=[6,5,3,2,8,10,9], k=3
seed window (first 4):   [6, 5, 3, 2]
heap (min):              [2, 5, 3, 6]
 
pop 2 → push 8   heap = [3, 5, 6, 8]    result = [2]
pop 3 → push 10  heap = [5, 8, 6, 10]   result = [2, 3]
pop 5 → push 9   heap = [6, 8, 9, 10]   result = [2, 3, 5]
drain:           pop 6, 8, 9, 10        result = [2, 3, 5, 6, 8, 9, 10] ✓

Solution

nearly_sorted.py
import heapq
 
def nearlySorted(arr: list[int], k: int) -> list[int]:
    h = arr[:k + 1]                      # seed with first k+1 elements
    heapq.heapify(h)                     # O(k)
    result: list[int] = []
 
    for i in range(k + 1, len(arr)):
        result.append(heapq.heappop(h))
        heapq.heappush(h, arr[i])
 
    while h:                              # drain the rest
        result.append(heapq.heappop(h))
    return result

Complexity

MetricValueReason
TimeO(n log k)Heap size stays at k+1, so each push/pop is O(log k). Over n elements: n log k.
SpaceO(k)Heap holds k+1 elements at any time. (Output array is required, not auxiliary.)

Edge Case Thinking

ScenarioHandling
k == 0Array is already sorted; loop runs n trivial pops.
k ≥ nDegenerates to a full sort — heap holds all elements, cost becomes O(n log n).
Wrong K claimIf the input isn’t actually K-sorted, the algorithm still runs but output won’t be fully sorted. Validate if untrusted.
DuplicatesHeap is not stable, so equal keys may swap order — doesn’t matter for sorted correctness.
Empty inputSeed slice arr[:k+1] is empty, both loops skip, return [].

Comments

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