题目:确定链表中是否有环,如果有环如何确定环的入口
题目链接:LeetCode-142. 环形链表 II

思路分析:快慢指针+环的特点
- 如果存在环,让快慢指针从头开始跑,快的每次走2步,慢的每次走1步,他们一定会相遇(因为当快指针进入环之后,每轮移动fast与slow的距离都会缩小1,直至二者相遇)。
- 如果不存在环,那快指针会先到达链表末尾(fast.Next==nil)。
- 画图可以算出,从相遇点到环入口,和从链表头到环入口的距离是相等的,所以可以使用两指针同时同步走,相遇点即使环入口。
图示说明环的特点

复杂度:时间复杂度:
O
(
n
)
O(n)
O(n)、空间复杂度:
O
(
1
)
O(1)
O(1)
Go代码
func detectCycle(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return nil
}
slow, fast := head, head
find := false
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
find = true
break
}
}
if !find {
return nil
}
slow = head
for {
if slow == fast {
break
}
slow = slow.Next
fast = fast.Next
}
return slow
}