Обзор решения: перемещение хвоста к голове – изучение различных методов на примерах кода

В этой статье блога мы углубимся в проблему перемещения хвоста связанного списка в его начало. Мы рассмотрим различные методы решения этой задачи и предоставим примеры кода на Python. К концу у вас будет полное понимание проблемы и различные подходы к ее решению.

Описание проблемы:
У нас есть односвязный список, нам нужно переместить последний узел (хвост) списка, чтобы он стал новым главой списка. Исходная голова должна стать предпоследним узлом.

Пример:
Рассмотрим следующий связанный список:
1 ->2 ->3 ->4 ->5

После перемещения хвоста в голову обновленный связанный список должен иметь следующий вид:
5 ->1 ->2 ->3 ->4

Метод 1: наивный подход
Самый простой подход предполагает обход всего связанного списка в поисках предпоследнего узла и последнего узла. Затем мы соответствующим образом обновляем указатели.

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
def move_tail_to_head(head):
    if not head or not head.next:
        return head
    curr = head
    prev = None
    while curr.next:
        prev = curr
        curr = curr.next
    curr.next = head
    prev.next = None
    return curr

Временная сложность: O(n), где n — количество узлов в связанном списке.

Метод 2: эффективный подход с двумя указателями
Чтобы избежать повторного обхода связанного списка, мы можем использовать два указателя: один из них опережает другой на k узлов. Как только первый указатель достигнет конца, второй указатель окажется в желаемой позиции для перемещения хвоста к голове.

def move_tail_to_head(head):
    if not head or not head.next:
        return head
    slow = head
    fast = head
    prev = None
    while fast and fast.next:
        prev = slow
        slow = slow.next
        fast = fast.next.next
    prev.next = None
    fast.next = head
    return fast

Временная сложность: O(n), где n — количество узлов в связанном списке.

Метод 3: рекурсивный подход
Мы также можем решить эту проблему, используя рекурсивную функцию. Функция рекурсивно переместит хвост в начало подсписка, начиная со второго узла, а затем соответствующим образом обновит указатели.

def move_tail_to_head(head):
    if not head or not head.next:
        return head
    def helper(node):
        if not node.next:
            return node
        new_head = helper(node.next)
        node.next.next = node
        node.next = None
        return new_head
    return helper(head)

Временная сложность: O(n), где n — количество узлов в связанном списке.

В этой статье мы рассмотрели различные способы перемещения хвоста связанного списка в его начало. Мы обсудили наивный подход, эффективный подход с использованием двух указателей и рекурсивный подход. Каждый метод предлагает свой взгляд на решение проблемы. В зависимости от конкретных требований и ограничений вашего приложения вы можете выбрать наиболее подходящий метод.

Не забудьте проанализировать временную и пространственную сложность каждого метода, чтобы принять обоснованное решение. Приятного кодирования!