Counting Sort runs in $O(n+k)$ time and $O(k)$ space in all cases, where $n$ is the number of elements and $k$ is the range of possible values; it’s efficient when $k$ is not much larger than $n$. It avoids comparisons by directly counting occurrences of each integer and reconstructing the sorted array.
Here is the idea:
histo of size c, initialised to all 0.histo[x] by 1.histo[v]| Case | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Best | $O(n+k)$ | $O(k)$ | Even if all elements are identical, initialization of the count array requires (O(k)). |
| Average | $O(n+k)$ | $O(k)$ | Dominated by both scanning input and reconstructing output. |
| Worst | $O(n+k)$ | $O(k)$ | Same as average; performance depends on (k). |
Stable sorting is possible if implemented carefully.
To make counting sort stable we use the following ideas:
Now the question is how to get the range of indices. This is easy: just calculate the prefix-sum of the histo array. This tells us to max index an element with that key could occupy.
Limitation: Not suitable when $k \gg n$.
function counting_sort(array A):
let n = length(A)
let k = maximum value in A
create count[0..k] initialized to 0
for each element x in A:
count[x] += 1
create output array B of size n
index = 0
for value from 0 to k:
while count[value] > 0:
B[index] = value
index += 1
count[value] -= 1
return B
Explanation:
Counting Sort is particularly useful in problems where:
Here are some examples:
HackerEarth – Shil and Birthday Present
Problem involves distributing gifts with bounded integer values; Counting Sort is the optimal way to sort and count efficiently.
Finding Pairs
Requires sorting bounded integers to quickly find valid pairs; Counting Sort avoids the overhead of comparison-based sorting.