题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
牛客网:链接
LeetCode同题:LeetCode141:Linked List Cycle LeetCode142:Linked List Cycle II
使用快慢指针,一个每次走一步,一个每次走两步。如果两个指针相遇,表明链表中存在环,并且两个指针相遇的结点一定在环中。随后,再用一个指针从头结点开始走,二者同时出发,相遇的节点即为环的入口结点。如果想得到环的节点数目,就从相遇的这个环中结点出发,一边继续向前移动一边计数,当再次回到这个结点时,就可以得到环中结点数目了。
具体实现:1. 分别用oneStep,twoStep指向链表头部,oneStep每次走一步,twoStep每次走二步,直到oneStep==twoStep找到二者在环中的相汇点。2. 当oneStep==twoStep时,twoStep所经过节点数为2x,oneStep所经过节点数为x,设闭环中有n个节点,twoStep比oneStep多走k圈有2x=kn+x;,nk=x;简单起见,可以看作k=1,oneStep实际走了一个环的步数,再让twoStep指向链表头部,oneStep位置不变,oneStep,twoStep每次走一步直到oneStep==twoStep;此时oneStep指向环的入口。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
if not pHead:
return None
oneStep = pHead
twoStep = pHead
'''不能在为None的时候相等!
while twoStep and twoStep.next:
下面这种判断 我比较好理解
但是LeetCode AC不过去 还是用while twoStep and twoStep.next好一些'''
while oneStep.next and twoStep.next.next:
oneStep = oneStep.next
twoStep = twoStep.next.next
if oneStep == twoStep:
twoStep = pHead
while twoStep != oneStep:
twoStep = twoStep.next
oneStep = oneStep.next
return oneStep
return None
思路2:用list存储,如果再次出现就是环的入口。list存的是ListNode,包括值和指针。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
if not pHead:
return None
result = []
while pHead:
if pHead not in result:
result.append(pHead)
else:
return pHead
pHead = pHead.next
return None