Учитывая заголовок односвязного списка, вернуть средний узел связанного списка.

Если есть два средних узла, вернуть второй средний узел.

Пример 1:

Ввод: head = [1,2,3,4,5] Вывод: [3,4,5] Объяснение: Средний узел списка — это узел 3.

Пример 2:

Ввод: head = [1,2,3,4,5,6] Вывод: [4,5,6] Объяснение: Поскольку в списке есть два средних узла со значениями 3 и 4, мы возвращаем второй.

Ограничения:

Количество узлов в списке находится в диапазоне [1, 100]. 1 <= Node.val <= 100

Решение

Подход 1: два прохода

  1. Найдите длину связанного списка, пройдясь по списку.
  2. Найдите средний узел, снова перейдя по списку к середине.
  3. Вернуть средний узел
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
def middle_node(head: ListNode) -> ListNode:
    length = 0
    current = head
    while current:
        length += 1
        current = current.next

    middle = length // 2
    current = head
    for _ in range(middle):
        current = current.next

    return current

Временная сложность: O(n) Пространственная сложность: O(1)

https://youtu.be/xcsDK3mziCM?embedable=true

Подход 2: один проход

  1. Используйте два указателя, один быстрый, а другой медленный.
  2. Перемещайте быстрый указатель на два узла за раз, а медленный указатель на один узел.
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
def middle_node(head: ListNode) -> ListNode:
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

    return slow

Временная сложность: O(n) Пространственная сложность: O(1)

https://youtu.be/vD0XdyM_Wwk?embedable=true