返回

LeetCode题解:环形链表 II的奥秘揭示

前端

环形链表II

简介

LeetCode题解中的一道经典题目——环形链表II,旨在考察您对链表数据结构和算法的掌握程度。题目要求您检测给定链表中是否存在环,并找到环的起点。

算法

检测链表中是否存在环的算法有很多种,其中最常见且最有效的方法之一是弗洛伊德循环检测法,也称为快慢指针法。该算法的基本思路如下:

  1. 初始化两个指针,一个称为快指针(fast),另一个称为慢指针(slow)。
  2. 让快指针每次前进一步,慢指针每次前进两步。
  3. 如果快指针和慢指针在某个时刻相遇,则说明链表中存在环。

如果链表中存在环,那么快指针和慢指针最终会相遇。这是因为快指针前进的速度是慢指针的两倍,因此总能在有限的时间内追上慢指针。

找到环的起点的算法也比较简单:

  1. 当快指针和慢指针相遇后,将慢指针重新指向链表的头部。
  2. 让快指针和慢指针同时前进,每次前进一步。
  3. 当快指针和慢指针再次相遇时,则说明环的起点就在它们相遇的前一个节点。

代码实现

以下是使用Python语言实现的环形链表II算法的代码:

def detect_cycle(head):
    """
    检测链表中是否存在环。

    参数:
        head: 链表的头节点。

    返回值:
        如果链表中存在环,则返回环的起点节点,否则返回None。
    """

    # 初始化快慢指针
    fast = head
    slow = head

    # 检测环
    while fast and fast.next:
        fast = fast.next.next
        slow = slow.next

        if fast == slow:
            return slow

    # 如果链表中不存在环,则返回None
    return None


def find_cycle_start(head, meeting_node):
    """
    找到环的起点。

    参数:
        head: 链表的头节点。
        meeting_node: 快指针和慢指针相遇的节点。

    返回值:
        环的起点节点。
    """

    # 将慢指针重新指向链表的头部
    slow = head

    # 让快指针和慢指针同时前进,每次前进一步
    while slow != meeting_node:
        slow = slow.next
        meeting_node = meeting_node.next

    # 返回环的起点
    return slow

复杂度分析

  • 时间复杂度:检测环的时间复杂度为O(n),其中n是链表的长度。找到环的起点的