Вы можете сделать это в O (N) на любом языке, в основном, как:
# Get min and max values O(n).
min = oldList[0]
max = oldList[0]
for i = 1 to oldList.size() - 1:
if oldList[i] < min:
min = oldList[i]
if oldList[i] > max:
max = oldList[i]
# Initialise boolean list O(n)
isInList = new boolean[max - min + 1]
for i = min to max:
isInList[i] = false
# Change booleans for values in old list O(n)
for i = 0 to oldList.size() - 1:
isInList[oldList[i] - min] = true
# Create new list from booleans O(n) (or O(1) based on integer range).
newList = []
for i = min to max:
if isInList[i - min]:
newList.append (i)
Я предполагаю, что здесь append
является O (1) операция, которая должна быть, если реализатор не было мозг умер. Таким образом, с k шагов каждый O (n), у вас все еще есть операция O (n).
Независимо от того, выполняются ли эти действия в вашем коде или выполняются ли они под обложками языка, это не имеет значения. В противном случае вы могли бы утверждать, что C qsort
была одной операцией, и теперь у вас есть святой грааль типа O (1) :-)
Как и многие люди, вы можете часто компрометировать космическую сложность во времени. Например, вышеизложенное работает только потому, что нам разрешено вводить переменные isInList
и newList
. Если это не было разрешено, следующим лучшим решением может быть сортировка списка (вероятно, не лучше O (n log n)), за которым следует операция O (n) (я думаю), чтобы удалить дубликаты.
В крайнем примере вы можете использовать тот же метод внепространства для сортировки произвольного числа 32-разрядных целых чисел (например, каждый из которых имеет только 255 или менее дубликатов) в O (n) времени, при условии, что вы можете выделить около четырех миллиардов байтов для хранения счетчиков.
Просто инициализируйте все отсчеты до нуля и пройдите через каждую позицию в своем списке, увеличивая счет на основе числа в этой позиции. Это O (n).
Затем запустите в начале списка и пропустите массив count, поместив в список много правильного значения. Это O (1), при этом 1 составляет около четырех миллиардов, но все же постоянное время :-)
Это тоже O (1) сложность пространства, но очень большая «1». Обычно компромиссы не так уж и серьезны.
Не попадайте в ловушку, думая, что O (независимо) сообщает вам все о скорости алгоритма. Алгоритм O (1) может занять 10 минут ... –