Содержание

876. Middle of the Linked List

Решение задачи 876 “Middle of the Linked List” с LeetCode.


Условие задачи

Дан не пустой, односвязный список с началом в узле head, необходимо вернуть указатель но узел, находящийся по середине списка. Если середина выпадает на 2 узла - вернуть необходимо второй

пример 1

Input: [1,2,3,4,5]
Output: Узел 3 из этого списка (Serialization: [3,4,5])

пример 2

Input: [1,2,3,4,5,6]
Output: Узел 4 из этого списка (Serialization: [4,5,6])

ограничения

  • Количество узлов от 1 до 100

Решение

Подсчет длины с двойным обходом

Идея алгоритма:

Первый раз проходом по списку для подсчета длины списка

Считаем индекс срединного элемента

Идем второй раз по списку до срединного элемента ( его индекс мы знаем ). Возвращаем этот элемент

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func middleNode(head *ListNode) *ListNode {
    l := 0
    
    cur := head
    for cur != nil {
        l++
        cur = cur.Next
    }
      middle := l/2
  
    cur = head
    for idx :=0; idx<middle;idx++{
        cur = cur.Next
    }
    
    return cur
    
}

Медленный и быстрый указатель

Идея алгоритма:

Завести два указателя. Медленный будет идти переходить на следующий элемент Быстрый - через элемент

Как только быстрый упрется в конец списка – медленны будет указывать на середину.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func middleNode(head *ListNode) *ListNode {
    slow := head
    fast := head
    
    for (fast != nil && fast.Next != nil) {
        slow = slow.Next
        fast = fast.Next.Next
    }
    
    return slow
    
}