Linked List Cycle II

题目描述

环形链表 II:

给定一个链表,返回链表开始入环的第一个节点,如果链表无环,返回null

示例:

输入:head = [3, 2, 0, -4], pos = 1, pos表示入环点
输出:tail connects to node index 1
输入:head = [1, 2], pos = 0
输出:tail connects to node index 0
输入:head = [1], pos = -1
输出:no cycle

解法

方法一:哈希表法

遍历节点,同时,在哈希表检查是否存在相同指针,如果存在则返回。 如果不存在,将当前节点存入哈希表。 直到节点遍历完,或者找到入环点。

  • 时间复杂度:O(n)

  • 空间复杂度:O(n)

func detectCycle(head *ListNode) *ListNode {
    nodeM := make(map[*ListNode]int)

    for head != nil {
        if _, ok := nodeM[head]; ok {
            return head
        }
        nodeM[head] = 1

        head = head.Next
    }

    return nil
}

方法二:快慢指针

快指针走两步,慢指针走一步,如果未找到相遇点,则不成环。 如果找到相遇点,此时相遇点一定在环内,保存相遇点。 使用两个指针,分别指向相遇点和链表头,每次都只走一步,直到相遇,即可找到入环点。

  • 时间复杂度:O(n)

  • 空间复杂度:O(1)

func detectCycle(head *ListNode) *ListNode {
    slow, fast := head, head
    for fast != nil && fast.Next != nil {
        slow = slow.Next
        fast = fast.Next.Next
        // 如果找到相遇点
        if slow == fast {
            // 一个指针指向链表头
            // 一个指针指向相遇点
            // 每次走一步 直到相遇
            fast = head
            for slow != fast {
                slow = slow.Next
                fast = fast.Next
            }
            return slow
        }
    }
    return nil
}

Last updated

Was this helpful?