题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路1:想到用字典存储每个节点。当某个节点出现的次数为2时返回该节点。
# -*- 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[pHead] = 1
else:
result[pHead] += 1
if result[pHead] == 2:
return pHead
pHead = pHead.next
return None
思路2:可以用两个指针来解决这个问题。先定义两个指针P1和P2指向链表的头结点。如果链表中的环有n个结点,指针P1先在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向的入口结点时,第一个指针已经围绕着揍了一圈又回到了入口结点。现在,关键问题在于怎么知道环中有几个结点呢?可以使用快慢指针,一个每次走一步,一个每次走两步。如果两个指针相遇,表明链表中存在环,并且两个指针相遇的结点一定在环中。随后,我们就从相遇的这个环中结点出发,一边继续向前移动一边计数,当再次回到这个结点时,就可以得到环中结点数目了。
具体实现: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
while twostep and twostep.next:
onestep = onestep.next
twostep = twostep.next.next
if onestep == twostep:
twostep = pHead
while onestep != twostep:
onestep = onestep.next
twostep = twostep.next
return onestep
return None