Sorting Algorithms Interview Patterns: Merge Sort, Quick Sort, Heap Sort, Counting Sort (2025)

Why Sorting Matters in Interviews

Sorting is foundational: dozens of problems become O(n log n) after sorting (two-sum, 3-sum, interval merge, meeting rooms, closest pairs). Know the trade-offs: stability, in-place vs extra space, best/average/worst case. Interviewers often ask why you chose a specific sort or expect you to implement one.

Merge Sort

Divide the array in half recursively until single elements; merge sorted halves. Merge: two-pointer merge of two sorted arrays into a third. Time: O(n log n) guaranteed (all cases). Space: O(n) auxiliary. Stable. Use merge sort when: stability is required, you are sorting linked lists (no random access needed), external sorting (data does not fit in memory — merge sorted chunks from disk).

def merge_sort(arr):
    if len(arr) <= 1: return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    result, i, j = [], 0, 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]: result.append(left[i]); i += 1
        else: result.append(right[j]); j += 1
    return result + left[i:] + right[j:]

Quick Sort

Choose a pivot; partition array into elements less than pivot, the pivot, and elements greater. Recurse on both halves. Time: O(n log n) average, O(n^2) worst (sorted array with naive pivot). Space: O(log n) stack (average). Not stable. In practice, faster than merge sort due to cache locality and low constant factor. Mitigate worst case: random pivot selection or median-of-three. Used in Python (Timsort uses merge sort + insertion sort), Java (dual-pivot quicksort for primitives).

Heap Sort

Build a max-heap from the array (O(n) via heapify). Repeatedly extract the max (O(log n)) and place at the end. Time: O(n log n) guaranteed. Space: O(1) in-place. Not stable. Less used in practice due to poor cache performance (non-sequential memory access). Good when guaranteed O(n log n) and O(1) space are both required.

Counting Sort and Radix Sort

Counting Sort: for integers in range [0, k]. Count occurrences, compute prefix sums, place elements. Time O(n+k), space O(k). Stable. Use when k is small (e.g., sorting by age, grade). Not comparison-based — bypasses the O(n log n) comparison lower bound.

Radix Sort: sort by each digit from least significant to most significant (LSD) using counting sort as the stable subroutine. Time O(d*(n+k)) where d = number of digits, k = base (10 for decimal). Used for sorting large integers or strings of fixed length. O(n) for fixed-size integers.

Timsort (Python / Java default)

Hybrid of merge sort and insertion sort. Identifies naturally occurring sorted runs in the input (many real-world arrays are partially sorted). Merges runs using a stack-based strategy. O(n) on already-sorted inputs, O(n log n) worst case. Stable. This is why Python sort and Java Arrays.sort(Object[]) are O(n) best case.

When to Use Which Sort

Sort Time Space Stable Use When
Merge Sort O(n log n) O(n) Yes Stability needed, linked lists, external sort
Quick Sort O(n log n) avg O(log n) No General purpose, primitives
Heap Sort O(n log n) O(1) No Guaranteed O(n log n) + O(1) space
Counting Sort O(n+k) O(k) Yes Small integer range
Radix Sort O(d*(n+k)) O(n+k) Yes Fixed-length integers/strings

Key Interview Points

  • Sorting a list of objects by multiple keys: use Python key=(lambda x: (x.a, x.b)) — Timsort is stable so multi-pass sorting works
  • Finding the kth largest element: QuickSelect — O(n) average, O(n^2) worst — or a min-heap of size k
  • External sort: merge sort chunks that fit in memory; merge sorted files using a k-way merge with a min-heap

{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “What is the time and space complexity of merge sort vs quicksort?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Merge sort: O(n log n) time in all cases (best, average, worst). O(n) space for the auxiliary merge buffer. Stable. Quicksort: O(n log n) average, O(n^2) worst case (sorted input with naive pivot). O(log n) stack space average (O(n) worst with bad pivot choices). Not stable. In practice, quicksort is 2-3x faster than merge sort on random data due to cache locality — sequential memory access during partitioning vs non-sequential during merge. Python uses Timsort (merge sort + insertion sort), O(n) on nearly sorted inputs. Java uses dual-pivot quicksort for primitives (average O(n log n) but with smaller constant) and Timsort for objects (stable).”
}
},
{
“@type”: “Question”,
“name”: “When should you use counting sort instead of a comparison sort?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Use counting sort when elements are non-negative integers in a small, known range [0, k]. Counting sort: count occurrences of each value, compute prefix sums, place elements in output array. O(n+k) time, O(k) space, stable. Beats O(n log n) comparison sorts when k = O(n). Examples: sort students by grade (0-100), sort characters in a string (k=26 or 256), sort ages (0-150), sort items by priority (1-5). Do NOT use when: k >> n (wastes space), elements are not integers, or elements span a large unknown range. Radix sort extends counting sort to multi-digit integers by sorting digit by digit, achieving O(d*n) where d is number of digits.”
}
},
{
“@type”: “Question”,
“name”: “How does the quickselect algorithm find the kth largest element in O(n)?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Quickselect is quicksort without fully sorting both halves. Partition the array around a pivot. If the pivot lands at index k (0-indexed from right), return it. If pivot index > k, recurse on the left half. If pivot index < k, recurse on the right half. Average O(n) because each partition eliminates about half the elements. Worst case O(n^2) with bad pivots — use random pivot to avoid. For guaranteed O(n) worst case, use the Median of Medians algorithm (more complex, rarely needed in interviews). Heap alternative: maintain a min-heap of size k. Push each element; when heap exceeds size k, pop the minimum. Final heap top is the kth largest. O(n log k) time, O(k) space."
}
},
{
"@type": "Question",
"name": "What is the difference between stable and unstable sorting?",
"acceptedAnswer": {
"@type": "Answer",
"text": "A stable sort preserves the relative order of elements with equal keys. An unstable sort may reorder equal elements. Example: sorting students by grade — stable sort keeps students with the same grade in their original order (e.g., alphabetical if previously sorted by name). Stable: merge sort, Timsort, counting sort, insertion sort. Unstable: quicksort, heap sort, selection sort. When stability matters: multi-key sorting (sort by date then by name — if the name sort is stable, records with the same name remain date-sorted). In Python, sort() is Timsort (stable), so you can chain sorts: sort by secondary key first, then primary key. In Java, Arrays.sort for primitives is unstable (dual-pivot quicksort); Arrays.sort for objects is stable (Timsort)."
}
},
{
"@type": "Question",
"name": "How do you implement an external sort for data larger than memory?",
"acceptedAnswer": {
"@type": "Answer",
"text": "External sort uses merge sort adapted for disk I/O. Phase 1 (run generation): read chunks of data that fit in memory, sort each chunk in memory (any in-memory sort), write sorted chunks (runs) to disk. With M bytes of memory and N bytes of data: creates N/M sorted runs. Phase 2 (merge): k-way merge of all sorted runs using a min-heap. Load the first element from each run into the heap. Extract the minimum, write to output, load the next element from that run's file. O(n log k) comparisons where k = number of runs. Minimize disk seeks by using large sequential reads/writes. This is how databases sort data for ORDER BY on large tables and how distributed systems like Hadoop implement MapReduce shuffle."
}
}
]
}

Asked at: Meta Interview Guide

Asked at: Apple Interview Guide

Asked at: LinkedIn Interview Guide

Asked at: Coinbase Interview Guide

Scroll to Top