While working on example code for an algorithm question, I came across the situation where I was sorting an input array, even though I only needed to have identical elements
Any sorting algorithm, even the most efficient ones, will require you to traverse the array multiple times. Grouping on the other hand can be done in exactly one iteration, depending on how you insist your result be formatted two:
groups = {}
for i in arr:
if i not in groups:
groups[i] = []
groups[i].append(i)
This is an extremely primitive loop ignoring many of the optimisations and idioms probably available in your language of choice, but results in this after just one iteration:
{1: [1, 1], 2: [2, 2], 3: [3], 4: [4, 4]}
If you have complex objects, you can choose any arbitrary attribute to group by as the dictionary key, so this is a very generic algorithm.
If you insist on your result being a flat list, you can achieve that easily:
result = []
for l in groups:
result += l
(Again, ignoring specific language optimisations and idioms.)
So there you have a constant time solution requiring at most one full iteration of the input and one smaller iteration of the intermediate grouping data structure. The space requirements depend on the specifics of the language, but are typically only whatever little bit of overhead the dictionary and list data structures incur.