快慢指针思路:思路有一个推理公示在里面,慢指针和快指针相遇是在环内相遇的,用a表示head到环起点的距离,b表示起点到相遇点的距离,c表示相遇点到环起点的距离
先求快指针遍历过的长度:a+(n+1)b+nc
慢指针遍历过的长度:a+b
快慢指针有2倍的关系
2(a+b)=a+(n+1)b+nc => a=(n-1)b+nc=c+(n-1)(b+c)
含义即是:a的距离就是c的距离+n倍的环的长度,所以可写出如下代码:
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func detectCycle(head *ListNode) *ListNode {
if head == nil || head.Next == nil{
return nil
}
slow, fast := head, head
for fast != nil{
slow = slow.Next
if fast.Next == nil{
return nil
}
fast = fast.Next.Next
if slow == fast{
p := head
for p != slow{
p = p.Next
slow = slow.Next
}
return p
}
}
return nil
}