Лучший случай - O(n log n)
. Выполните сортировку кучи для исходного массива: O(n log n)
по времени, O(1)
/ по месту в пространстве. Затем последовательно пропустите массив с двумя индексами (source & dest), чтобы свернуть повторения. Это имеет побочный эффект не сохранения первоначального порядка, но, поскольку «удалить дубликаты» не указывает, какие дубликаты следует удалить (первый? Второй? Последний?), Я надеюсь, что вам все равно, что заказ потерян .
Если вы хотите сохранить первоначальный порядок, нет способа сделать что-то на месте. Но это тривиально, если вы создаете массив указателей на элементы в исходном массиве, выполняете всю свою работу с указателями и используете их, чтобы свернуть исходный массив в конце.
Любой, кто утверждает, что это может быть сделано в O(n)
время и на месте, просто неправ, по модулю некоторые аргументы о том, что означает O(n)
и на месте. Одно очевидное псевдо-решение, если ваши элементы представляют собой 32-разрядные целые числа, - это использование 4-гигабитного битового массива (размером 512 мегабайт), инициализированного для всех нулей, при включении, когда вы видите это число, при включении немного бит был уже включен. Конечно, тогда вы используете тот факт, что n
ограничен константой, так что технически все это O(1)
, но с ужасным постоянным фактором. Однако я упоминаю этот подход, поскольку, если n
ограничен небольшой константой - например, если у вас есть 16-разрядные целые числа - это очень практичное решение.