142. Linked List Cycle II
知识点:two pointers
1. 原题
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
Note: Do not modify the linked list.
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.
Example 2:
Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.
Example 3:
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.
Follow-up:
Can you solve it without using extra space?
2. 题意
判断一个list中是否有环,若有,则返回环的起点;否则,返回None
3. 思路
如只是判断是否有环,可使快指针一次走两步,慢指针一次走一步,只要这两个指针能相等,就是有环。
但是对于需要找到环的起点,则需要进行分析。(图片来自南郭子綦,非常感谢)
首先采用快两步,慢一步的思路,使两个指针相遇用来判断是否有环,即为图片中的相遇点。在相遇时,慢指针走过 k + M 的距离;而快指针走过 k + M + nL 的距离,n是多走的圈数。
2(k + M)= k + M + nL
k = n*L - M
所以在相遇之后,将慢指针放回head,快指针留在相遇点代表被减去的距离M。之后快和慢指针均一步一步走,当两个指针相遇的时候,就是起点的地方。
4. 代码
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head==None or head.next==None:
return None
f=s=head
while f and f.next:
f=f.next.next
s=s.next
if f==s:
break
if f==s:
s=head
while f!=s:
f=f.next
s=s.next
return s
return None
5. Reference
https://www.cnblogs.com/zuoyuan/p/3701877.html