Существует третье решение, на этот раз с использованием O(log(n))
памяти и O(n log(n))
времени, таким образом занимая золотую середину между двумя решениями в ответе Марка.
Это, по сути, обратный спуск по порядку бинарного дерева [O(log(n))
], за исключением того, что на каждом шаге вам нужно найти вершину дерева [O(n)
]:
- Разделить список на две части
- Записаться во вторую половину списка
- Вывести значение в средней точке
- Рекурс в первую половину
Вот решение на Python (я не знаю C #):
def findMidpoint(head, tail):
pos, mid = head, head
while pos is not tail and pos.next is not tail:
pos, mid = pos.next.next, mid.next
return mid
def printReversed(head, tail=None):
if head is not tail:
mid = findMidpoint(head, tail)
printReversed(mid.next, tail)
print mid.value,
printReversed(head, mid)
Это может быть переделано с использованием итерации вместо рекурсии, но ценой ясности.
Например, для списка с миллионным входом три решения имеют порядок:
Solution Memory Performance
=========================================
Marc #1 4MB 1 million operations
Mine 80B 20 million operations
Marc #2 4B 1 trillion operations