1. 链表中是否有环
思路:设置快慢指针,fast和low,两者都从链表头出发,快指针每次走两步,慢指针每次走一步,若存在环,则快慢指针会在某个链表节点相遇
if not head or not head.next:
return False
// 定义快慢指针初始位置不一样,是因为循环条件先于循环体
// 如定义一样的初始位置,则需要使用do while循环
slow = head
fast = head.next
while slow!=fast:
// 当链表中不存在环时,快指针先到达链表尾部
if not fast or not fast.next:
return False
slow =slow.next
fast = fast.next.next
return True
class Solution:
def hasCycle(self, head: ListNode) -> bool:
fast = head
slow = head
while fast and fast.next:
slow =head.next;
fast = fast.next.next
if slow ==fast:
return True
return False
时间复杂度:O(N)
空间复杂度:O(1)
解法2:hash表
遍历所有的节点,每次遍历一个节点的时候,判断此节点是否存在于hash表中,如果存在则表示存在环,如果不存在则将该节点加入hash表中
class Solution:
def hasCycle(self, head: ListNode) -> bool:
seen = set()
while head:
if head in seen:
return True
seen.add(head)
head = head.next
return False
时间复杂度:O(N)
空间复杂度:O(N)
2. 链表中环的入口节点
给定一个链表,若其中包含环,请找出该链表的环的入口节点,否则,输出null
解题思路:
- 设置快慢指针,fast和low,两者都从链表头出发,快指针每次走两步,慢指针每次走一步,若存在环,则快慢指针会在某个链表节点相遇
- 两指针分别从链表头和相遇点出发,则他们的相遇点就是环的入口处
// 如果没有环,返回null
if not fast.next or not fast.next.next:
return null
// 如果有环,fast指针不变,还是在相遇点
slow = head //slow在链表头
while slow!=fast:
slow =slow.next
fast = fast.next
return fast