Three Number Sort
Three Number Sort
Category
Sorting
Difficulty
Medium
Problem Statement
Given an array of integers that only contains three distinct values and a separate array defining the desired order of those three values, sort the main array in-place according to that order. For example, given [1, 0, 0, -1, -1, 0, 1, 1] and order [0, 1, -1], the result should be [0, 0, 0, 1, 1, 1, -1, -1].
Intuition
This is a variant of the Dutch National Flag problem. Since there are only three distinct values, we can partition the array in a single pass using three pointers. One pointer tracks where the next "first" value should go, another tracks where the next "third" value should go, and a scanning pointer moves through the array.
Approach
- Let the three values in order be
first,second, andthird. - Initialize three pointers:
low = 0,mid = 0,high = length - 1. - While
mid <= high:- If
array[mid] == first: swaparray[low]andarray[mid], increment bothlowandmid. - If
array[mid] == second: just incrementmid(it is in the correct middle zone). - If
array[mid] == third: swaparray[mid]andarray[high], decrementhigh(do not incrementmidbecause the swapped element needs inspection).
- If
- Return the array.
Pseudocode
function threeNumberSort(array, order):
first = order[0]
third = order[2]
low = 0
mid = 0
high = length(array) - 1
while mid <= high:
if array[mid] == first:
swap(array[low], array[mid])
low += 1
mid += 1
else if array[mid] == third:
swap(array[mid], array[high])
high -= 1
else:
mid += 1
return array
Time & Space Complexity
- Time: O(n) — Single pass through the array. Each element is processed at most twice (once by
mid, potentially once more after a swap fromhigh). - Space: O(1) — Only three pointer variables are used.
Key Insights
- This is essentially the Dutch National Flag algorithm attributed to Dijkstra.
- When swapping with
high, we do not advancemidbecause the element swapped fromhighhas not been inspected yet. - When swapping with
low, we can safely advancemidbecauselow <= midand everything beforemidhas already been categorized. - An alternative two-pass approach: first move all
firstvalues to the front, then move allthirdvalues to the back.
Edge Cases
- Array contains only one of the three values — all pointers converge quickly.
- Array contains only two of the three values — one partition remains empty.
- Array is already sorted in the desired order —
midadvances through without swaps. - Single-element array — already sorted.