142. 环形链表 II
https://leetcode-cn.com/problems/linked-list-cycle-ii/
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
说明:不允许修改给定的链表。不用额外空间解决此题。
代码详解
第一阶段
链表头部到链表入口 有 a 个节点(不计链表入口节点), 链表环 有 b 个节点
设两指针分别走了 f,s 步
- f = 2s (f每轮走两步,s每轮走一步)①
- f = s + nb (多走n个环)②
由①②可得,第一次相遇时
- f = 2nb
- s = nb
第二阶段
如果让指针从链表头部一直向前走并统计步数k,那么所有 走到链表入口节点时的步数 是:k=a+nb(先走 a 步到入口节点,之后每绕 1 圈环( b 步)都会再次到入口节点)。
- k=a+nb (环入口)
又因 s = nb(第一次相遇),所以,让慢指针再走a步即可到达环入口
fast指针重新指向head,然后变慢每轮只走一步
slow和fast同时每轮向前走 1 步,当 fast 指针走到 f=a 步时,slow 指针走到步s = a+nb,此时 两指针再次重合,并同时指向链表环入口 。
# 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
"""
fast, slow = head, head
while True:
if not (fast and fast.next):
return
fast, slow = fast.next.next, slow.next
if fast == slow: # 第一次相遇
break
fast = head # fast重新指向head,并且开始每轮走1步
while fast != slow:
fast, slow = fast.next, slow.next
return fast
141.环形链表
https://leetcode-cn.com/problems/linked-list-cycle/
给定一个链表,判断链表中是否有环。
快慢指针
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if not (head and head.next):
return False
# 定义两个指针,慢指针,快指针
fast, slow = head, head
while fast and fast.next:
# slow每次走一步,fast每次走两步
slow = slow.next
fast = fast.next.next
if fast == slow:
return True
return False