55. 链表中环的入口结点

题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。


思路
链表有环的意思就是,最后一个节点的next指向了前面的某个节点,链表没有None的链表尾部出口。
思路一:
引入辅助空间,用一个列表保存已经遍历过的节点,如果再次出现,则说明这个节点就是链表环的入口节点。
思路二:
设:链表长度为N,链表环长度为m
1.用两个指针来遍历这个链表,一个每次走一步,一个每次走两步,两个指针会在链表环中的节点相遇。
2.然后继续遍历其中的一个,步长为1,可以计算出链表环中节点的个数m。
3.重新遍历链表,一个指针从头结点0开始(距链表环入口节点N-m),另一个节点从节点m开始(距链表环入口节点也是N-m),两个节点会在链表环入口节点处相遇,于是得到链表环入口节点。


代码实现
思路一:

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        hashList= []
        headNode = pHead
        while headNode:
            if(headNode == None):
                return None
            if(headNode in hashList):
                return headNode
            else:
                hashList.append(headNode)
            headNode = headNode.next

思路二:

# -*- 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 or not pHead.next or not pHead.next.next:
            return None
        # 用两个指针来遍历这个链表,一个每次走一步,一个每次走两步,两个指针会在链表环中的节点相遇。
        headSlow = pHead
        headFast = pHead.next
        while (headSlow != headFast):
            if headSlow.next == None or headFast.next.next == None:
                return None 
            headSlow = headSlow.next
            headFast = headFast.next.next
        # 此时headSlow = headFast 在环中某节点相遇
        # 继续遍历其中的一个,步长为1,遍历headFast
        count = 1
        headFast = headFast.next
        while(headSlow != headFast):
            headFast = headFast.next
            count += 1
        # count为链表环中节点的个数

        # 重新遍历链表,一个指针从头结点0开始(距链表环节点N-m),另一个节点从节点m开始(距链表环入口节点是N-m)
        # 两个节点会在链表环入口节点处相遇,于是得到链表环入口节点。
        headSlow = pHead
        headFast = pHead
        for i in range(count):
            headFast = headFast.next
        while(headSlow != headFast):
            headSlow = headSlow.next
            headFast = headFast.next
        return headSlow