利用两个指针p1,p2(每次分别增1和2)来进行判断
使用两个指针 : slow和fast , slow每次移动一位,fast每次移动两位,当发生以下条件之一时结束,时间复杂度为O(n)。
- 首先一个终止的条件是指针p2遇到NULL节点.这说明不存在闭环
- 另外一个条件式当两个指针相遇就终止,这说明有闭环
为什么有环的情况下二者一定会相遇呢?因为fast先进入环,在slow进入之后,如果把slow看作在前面,fast在后面每次循环都向slow靠近1,所以一定会相遇,而不会出现fast直接跳过slow的情况。
def checkclosedcycle(head):
"""检查当前链表是否存在闭环。"""
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow is fast and fast is not None:
return True
return False
扩展问题
LeetCode Questions
Linked List Cycle
Given a linked list, determine if it has a cycle in it.
Follow up: Can you solve it without using extra space?
如何判断一个单链表中有环?
Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return
null
.Follow up: Can you solve it without using extra space?
如何找到环的第一个节点?
在网上搜集了一下这个问题相关的一些问题,思路开阔了不少,总结如下:
1. 环的长度是多少?
2. 如何找到环中第一个节点(即Linked List Cycle II)?
3. 如何将有环的链表变成单链表(解除环)?
4. 如何判断两个单链表是否有交点?如何找到第一个相交的节点?
首先我们看下面这张图:
设:链表头是X,环的第一个节点是Y,slow和fast第一次的交点是Z。各段的长度分别是a,b,c,如图所示。环的长度是L。slow和fast的速度分别是qs,qf。
下面我们来挨个问题分析。
1. 环的长度是多少?
方法一(网上都是这个答案):
第一次相遇后,让slow,fast继续走,记录到下次相遇时循环了几次。因为当fast第二次到达Z点时,fast走了一圈,slow走了半圈,而当fast第三次到达Z点时,fast走了两圈,slow走了一圈,正好还在Z点相遇。
方法二:
第一次相遇后,让fast停着不走了,slow继