题目描述:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例:
1) 输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
2)输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
3) 输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
思路1:
和之前判断是否有环一样,使用set,当一个结点已经在set时,就表明这个结点是这个环的入口。
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
s = set()
while head:
if head in s:
return head
else:
s.add(head)
head = head.next
return None
时间复杂度和空间复杂度都是O(N)。
思路2:
和之前判断是否有环一样,使用快慢指针的思想,但是快慢指针相遇的地方,不一定是环的入口,如何找到环的入口需要再进行数学推导。
具体地:
根据这个思路代码为:
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
fast = head
low = head
pre = head
flag = False
while low and fast and fast.next:
low = low.next
fast = fast.next.next
if low is fast: # 相遇
flag = True
break
if flag: # 找入环的结点
while pre != low:
low = low.next
pre = pre.next
return pre
else:
return None
时间复杂度为O(N), 空间复杂度为O(1),因为空间上其实只用了三个指针。