解法一:(set)T:O(n) S:O(n)
用一个set遍历链表,无论成环还是不成环,都会遍历所有的节点一次,区别在于若成环会返回一个访问过的节点,不成环会返回null
# 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
"""
visited = set()
node = head
while node is not None:
if node in visited:
return node
else:
visited.add(node)
node = node.next
return None
解法二:Floyd算法
第一阶段:快慢指针(快指针每次移动两个节点,慢指针每次移动一个),记录相遇的节点
第二阶段:找到环的入口,ptr1指向链表的头,ptr2指向相遇的节点
证明过程如下:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getInter(self, head):
tortoise = head
hare = head
while hare is not None and hare.next is not None:
tortoise = tortoise.next
hare = hare.next.next
if tortoise == hare:
return tortoise
return None
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head is None:
return head
interaction = self.getInter(head)
if interaction is None:
return None
ptr1 = head
ptr2 = interaction
while ptr1 != ptr2:
ptr1 = ptr1.next
ptr2 = ptr2.next
return ptr1