题目
代码实现:
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func detectCycle(head *ListNode) *ListNode {
fast,slow := head,head
for slow != nil &&fast != nil && fast.Next != nil {
fast = fast.Next.Next
slow = slow.Next
if fast == slow {
fast = head
for fast != slow {
fast = fast.Next
slow = slow.Next
}
return slow
}
}
return nil
}
/*
func detectCycle(head *ListNode) *ListNode {
fast, slow := head, head
for {
if fast == nil || fast.Next == nil {
return nil // 无环
}
fast = fast.Next.Next
slow = slow.Next
if fast == slow {
break //找到第一次相遇点
}
}
slow = head
for fast != slow {
fast = fast.Next
slow = slow.Next
}
return slow
}
*/
解题思路:第一次相遇时,假设慢指针 slow 走了 k 步,那么快指针 fast 一定走了 2k 步,也就是说比 slow 多走了 k 步(也就是环的长度)。设相遇点到环的距离为m,环的起点距头结点head的距离为k-m,从头结点再走k-m步就可以到达环的起点。注意相遇点继续前进k-m正好到达环的起点。把快慢指针中的任一个重新指向 head,然后两个指针同速前进,k - m 步后就会相遇,相遇之处就是环的起点。