Disperse Duplicates in an Array
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Sometimes the goal is not to remove duplicates from an array but to spread them out so equal values are separated as much as possible. This kind of rearrangement appears in scheduling, task queues, and UI ordering problems where repeated items should not appear back to back.
Clarify the Goal First
There are two closely related versions of this problem:
- strict rearrangement, where no two equal values may be adjacent
- best-effort dispersion, where perfect separation may be impossible and you still want the duplicates spread out as evenly as possible
For the strict version, some inputs have no valid answer. If one value appears too often, eventually two copies must end up next to each other. A simple example is ["A", "A", "A", "B"]. There are not enough other elements to fully separate all three A values.
A Greedy Heap-Based Strategy
The standard approach counts frequencies, then repeatedly places the most frequent remaining value that is not the same as the one just placed. A max heap works well for that because it always lets you pull the current highest-frequency candidate.
Here is a Python implementation that returns a rearranged array when possible and raises an error when strict dispersion cannot be achieved.
Typical output:
The exact order can vary when several values have the same frequency, but the idea is the same: always use the best available value while keeping the previous one temporarily out of circulation.
Why the Greedy Approach Works
The highest-frequency value is the hardest one to place. If you postpone it too long, you may run out of separating values and be forced into adjacent duplicates later. Greedily placing the most constrained item first reduces that risk.
The temporary prev_value storage is the key detail. After placing a value, you do not immediately let the same value compete for the next slot. You wait one round, which prevents instant repetition.
The overall complexity is usually O(n log k), where n is the array length and k is the number of distinct values. Counting is linear, and each heap push or pop costs logarithmic time in the number of unique elements.
Best-Effort Dispersion When a Perfect Answer Does Not Exist
In some applications, you do not want to fail just because strict separation is impossible. You want the duplicates as spread out as possible. In that case, you can still use the same heap strategy and drop the final error check, or define a scoring rule based on distance between equal elements.
For example, a playlist generator may prefer a sequence like A, B, A, C, A over A, A, A, B, C even though both contain the same values. The strict algorithm provides a strong starting point, and a best-effort version can keep placing the least harmful choice when no perfect choice remains.
Common Pitfalls
The first mistake is confusing this problem with deduplication. Removing duplicates is easier but changes the data. Dispersion keeps all occurrences and only changes their order.
Another pitfall is assuming a solution always exists. If one value dominates the array, no algorithm can fully separate every duplicate. Your code should either detect that case or define what "best effort" means.
A third issue is relying on sort order alone. Sorting groups identical values together, which is the opposite of what you want. You need frequency-aware placement, not simple ordering.
Finally, watch stability expectations. A heap-based solution does not preserve original order among equal-frequency items unless you add an explicit tie-break rule. If partial order preservation matters, that requirement should shape the data structure you choose.
Summary
- Dispersing duplicates means rearranging values so equal items are separated, not removed.
- A max heap plus frequency counts is a standard greedy solution.
- The same value should be held back for one step after it is placed.
- Some arrays cannot be rearranged to avoid adjacent duplicates completely.
- Decide early whether your application needs strict validity or a best-effort arrangement.

