题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路(参考)
1.首先确定链表中是否存在环
方法:
设置快慢指针,快指针每次走两步,慢指针走一步。链表中无环则最终快指针为None,若有环快指针和慢指针一定相交。
证明:
设置快慢指针fast和low,fast每次走两步,low每次走一步。假如有环,两者一定会相遇(因为low一旦进环,可看作fast追赶low,两个相隔一个节点时下一步即可追上,相隔两个节点时下下步即可追上)。
2.找到环的入口点
方法:
快指针指向头节点,慢指针指向相遇点,则快慢指针同时移动一步,最终交于点(入口节点)。
证明:
设头节点到环入口节点个数为a,环入口到指针交点节点个数为b,指针交点到环入口节点个数为c。
设快指针走过2l个节点,慢指针走过l个节点。
快指针走过的节点数为:2l = a+(b+c)*n+b
慢指针走过的节点数为:l = a+b
即a+(b+c)*n+b = 2*(a+b)整理得:a =( n-1)(b+c)+c
即代表:链表头到环入口的距离=相遇点到环入口的距离+(k-1)圈环长度。
代码
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def EntryNodeOfLoop(self, pHead): # write code here #首先判断是否存在环 fastHead = pHead slowHead = pHead while(fastHead and fastHead.next): fastHead = fastHead.next.next slowHead = slowHead.next if fastHead == slowHead: break #本想用快慢指针是否相等作为判断条件,但初始时快慢指针是相等的 if fastHead==None or fastHead.next==None: return None fastHead = pHead while(fastHead!=slowHead): fastHead = fastHead.next slowHead = slowHead.next return fastHead