141环形链表
1.最长就10000直接遍历计数,超过10000就是有环。。。。
空间复杂度O(1)
class Solution:
def hasCycle(self, head: ListNode) -> bool:
i=0
while head:
i+=1
head=head.next
if i>10000:
return True
return False
2.用set检测是否有重复元素
python的set类中储存不重复的元素,用set的特性检测node是否重复
空间复杂度O(n),需要储存链表所有节点
class Solution:
def hasCycle(self, head: ListNode) -> bool:
s=set()
while head:
if head in s:
return True
s.add(head)
head=head.next
return False
3.快慢指针
慢指针一次走一步,快指针一次走两步,如果有环的话,快慢指针会相遇
空间复杂度O(1),只需要储存两个指针
class Solution:
def hasCycle(self, head: ListNode) -> bool:
#用try语句检测head与head.next是否为None
try:
slow,fast=head,head.next
while fast:
if slow==fast:
return True
slow=slow.next
fast=fast.next.next
return False
except:
return False
142环形链表2
1.set()方法
直接返回set中重复的那个元素,空间复杂度O(n)
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
s=set()
while head:
if head in s:
return head
s.add(head)
head=head.next
return None
2.双指针法
空间复杂度O(1)只要储存指针
快指针f一次走两步,慢指针s走1步
①首先判断有环无环,同141
有环->快慢指针相遇,设链表长为a+b,b为环的长度
此时f=2s,f=s+nb(快指针比慢指针多走了n圈)
则s=nb
②找环的入口
从head开始,慢指针走的步数为s=a+nb时,则为换的入口处
由于快慢指针相遇时s走了nb步,那么s再走a步即为环的入口
重新设置一个指针p从head开始走,s与p同时前进,s、p相遇时则为环的入口
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
s,f,p=head,head,head
###使用try语句来处理边界,比如空链表和长度为1的链表####
try:
while f:
s=s.next
f=f.next.next
if s==f:
while p!=s:
p=p.next
s=s.next
return p
return None
except:
return None