How can I count the unique numbers in an array without rearranging the array elements?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Counting unique values without rearranging an array is straightforward if you are allowed extra memory, and much more constrained if you are not. The first design decision is whether “do not rearrange” means “preserve the array exactly” or whether auxiliary storage is acceptable.
The Standard Solution Uses a Set
If the array must remain in its original order and you only need the count, a set is the simplest and most efficient solution. As you scan the array, insert each value into the set. Duplicate insertions do nothing, so the final size of the set is the number of distinct elements.
Output:
This runs in O(n) average time and uses O(u) extra space, where u is the number of unique values.
Why Preserving Order Does Not Change the Counting Logic
People often mention “without rearranging the array” because sorting is a common distinct-count technique. Sorting groups equal values together, but it mutates the array or requires a sorted copy. If mutation is not allowed, a set avoids the problem entirely because it never changes the input sequence.
The array stays exactly as it started.
If You Need the Unique Values in First-Seen Order
Sometimes the real need is not only the count, but also the sequence of first appearances. You can collect both with one pass.
Output:
Then len(ordered) is your unique count.
What If Extra Space Is Restricted
If you are not allowed to rearrange the array and also not allowed significant extra storage, the problem gets harder. Without storing what you have seen, the only exact alternative is repeated scanning.
This uses constant extra space, but it takes O(n^2) time. That is the usual tradeoff when you forbid both mutation and storage.
Small Numeric Ranges Allow a Better Space Tradeoff
If the values are integers from a known small range, a boolean array or count array can be cheaper than a hash set.
That is still auxiliary space, but it is predictable and often faster than hashing.
Choose the Constraint That Actually Matters
In real code, the set-based solution is usually correct because it is simple, fast, and does not alter the array. If the requirement is “do not rearrange the elements,” that does not automatically mean “use no extra memory.” Those are different constraints and should not be mixed together.
Common Pitfalls
- Assuming that preserving the array means a set is forbidden when the requirement only bans rearrangement.
- Sorting the array in place and accidentally violating the “do not rearrange” rule.
- Using a constant-space nested-loop solution when a set would be simpler and much faster.
- Forgetting that counting unique values and finding non-repeating values are different problems.
- Choosing a fixed-size marker array without confirming the numeric range is small enough.
Summary
- A set gives the cleanest exact solution when the array must stay in its original order.
- The set approach runs in
O(n)average time and leaves the input untouched. - Constant extra space is possible only with slower repeated scanning unless other assumptions hold.
- A small known numeric range can justify a boolean or count array.
- Clarify whether the real constraint is “no rearrangement,” “low memory,” or both.

