essay

hot100-环形链表I和II

#算法

hot100——环形链表I和II

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

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

image.png

输入:head = [3,2,0,-4], pos = 1

输出:返回索引为 1 的链表节点

解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

image.png

输入:head = [1,2], pos = 0

输出:返回索引为 0 的链表节点

解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

image.png

输入:head = [1], pos = -1

输出:返回 null

解释:链表中没有环。

提示:

链表中节点的数目范围在范围 [0, 104] 内

-105 <= Node.val <= 105

pos 的值为 -1 或者链表中的一个有效索引

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
 
// detectCycle 检测链表中是否存在环,若存在则返回环的入口节点,否则返回 nil
func detectCycle(head *ListNode) *ListNode {
    // 初始化快慢指针,都从链表头开始
    slow, fast := head, head
 
    // 使用快慢指针检测是否存在环
    // 循环条件:fast 和 fast.Next 都不能为 nil,确保 fast.Next.Next 安全访问
    for fast != nil && fast.Next != nil {
        slow = slow.Next           // 慢指针每次走 1 步
        fast = fast.Next.Next      // 快指针每次走 2 步
 
        // 如果快慢指针相遇,说明链表中存在环
        if slow == fast {
            // 此时 slow(或 fast)是环内的某个相遇点
            // 根据 Floyd 算法第二阶段:找环入口
            
            // 将 curr 指针重置到链表头部
            curr := head
            
            // curr 从头开始,slow 从相遇点开始,两者以相同速度(每次1步)前进
            // 它们第一次相遇的位置就是环的入口节点
            for curr != slow {
                curr = curr.Next
                slow = slow.Next
            }
            
            // 返回环的入口节点
            return curr
        }
    }
 
    // 如果循环正常结束(fast 走到 nil),说明链表无环
    return nil
}
comments如果有不同意见或者补充,直接留在这里。
contact

在别处继续找到我

如果你想聊技术、设计,或者只是打个招呼。

暂未配置外部链接