给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
双指针法:
两个指针一个遍历速度快,一个遍历速度慢,如果有环,则快指针一定会赶上慢指针与之相遇(想象一下两个人围着操场跑步,跑的快的人一定会在后来追上跑的慢的人)。这里快指针走两步,慢指针走一步
Python实现:
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
return True
return False
环形链表II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。
思路:先用快慢指针判断是否存在环,如果存在环再进节点判断。
这里要注意的是,快慢指针相遇的节点不一定是环开始的节点,假设环开始的节点是A,对于存在的环的链表,假设快慢指针在进入环之前从head走到A的路程为a,进入环之后离环开始的节点长度为b,我们想要得到的就是a,
而a+b就是慢指针走过的节点数,而fast因为一直是slow的两倍速度,所以fast走过的路程是slow的两倍,那么快指针走过的路程就是2*(a+b),要理解这个地方!!!
注意的是,fast和slow现在都在同一个节点假设为B,那么如果slow继续走一圈走到B还需要走a+b(fast走过的路程-slow走过的路程)的路程,而A到B的路程是b,所以slow还需要再走a这个长度就能到节点A,同时,又因为头指针到A的距离也为a,所以所以(重点来了!!)头指针到A的距离和slow到A的距离都是a!那么我们只需要使head和slow同时往前走a这个长度就能在入环节点A处相遇,就能返回当前值!
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 先判断是否有环
fast=slow=head
# temp=head
while fast and fast.next:
fast=fast.next.next
slow=slow.next
if fast==slow: # 相遇的地方不一定是交点
temp=head # temp从head开始走
while slow!=temp: # 两个一起往前走a的长度然后在入环节点处相遇
slow=slow.next
temp=temp.next
return slow
return None