链表中环的入口节点
题目
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
解析
- 如何判断里面是否有环
利用快慢指针,快指针每次走两步,慢指针每次走一步,如果有环的话,那么当快慢指针在环中循环时,肯定有相遇的一天;如果没有环,那么快指针会先走到None。
第一步,先判断有没有环
第二步,找入口点
那如何找入口点呢?fast走的步数与slow走的步数是相等的,只不过长度不等。
假设slow走了 的长度,那么fast就走了 :
设 为从起点到环入口点的距离, 为从入口点到相遇点的距离,即蓝色长度; 为环的长度。
slow走的长度 ,其中 是slow走的圈数;
fast走的长度 ,其中 是fast走的圈数;
那么有: ,
所以有:
即起始点到环入口的距离x等于数个环的长度再加上从相遇点到起始点的长度。
于是,思路就来了,再设计两个速度一样的指针,一个指针从原点开始走,另一个指针从相遇点开始走,当从原点走的指针走到入口点的时候,另一个指针一定也到达了入口点(可能走了几圈环的距离+c-a).
算法步骤:
- 边界条件:PHead=none
- 判断是否有环:while 快指针和快指针的next存在的话就进入循环,直到两个两个相遇再结束;如果不存在就跳出了循环,然后判断快指针或者快指针的next是不是为空,如果为空就返回none
- 找到入口节点
# -*- 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 pHead == None:
return None
fastPointer = pHead
slowPointer = pHead
while fastPointer and fastPointer.next:
fastPointer = fastPointer.next.next
slowPointer = slowPointer.next
if fastPointer == slowPointer:
break
if fastPointer == None or fastPointer.next == None:
return None
# 找入口,初始化fastpointer,改变其性质与slow一样
fastPointer = pHead
while fastPointer != slowPointer:
fastPointer = fastPointer.next
slowPointer = slowPointer.next
return fastPointer