剑指offer55-链表中环的入口结点

题目描述

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

代码

解法一:暴力循环

  1. 遍历单链表的每个结点
  2. 如果当前结点地址没有出现在set中,则存入set中
  3. 否则,出现在set中,则当前结点就是环的入口结点
  4. 整个单链表遍历完,若没出现在set中,则不存在环
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        a={}
        while pHead:
            if pHead not in a:
                a[pHead]=1
                pHead=pHead.next
            else:
                return pHead
        return None

解法二:快慢指针

                                                      

步骤:

    1. 初始化:快指针fast指向头结点, 慢指针slow指向头结点
    2. 让fast一次走两步, slow一次走一步,第一次相遇在C处,停止
    3. 然后让fast指向头结点,slow原地不动,让后fast,slow每次走一步,当再次相遇,就是入口结点。

思路:

如果慢指针slow第一次走到了B点处,距离C点处还有距离Y,那么fast指针应该停留在D点处,且BD距离为Y(图中所示是假设快指针走了一圈就相遇,为了便于分析),
也就是DB+BC=2Y,(因为fast一次走2步,慢指针一次走1步,并且相遇在C处)
在C点处,此时慢指针slow走的点为ABC,距离为X+Y,而快指针fast走的点为ABCDBC,距离为2X+2Y,
又因为:AB=X,BC=Y,快指针走了2次BC,所以CDB距离为X,而AB距离也为X。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        fast=pHead
        slow=pHead
        while fast and fast.next:
            fast=fast.next.next
            slow=slow.next
            if fast==slow:
                break
        if fast==None or fast.next==None:
            return None
        fast=pHead
        while fast!=slow:
            fast=fast.next
            slow=slow.next
        return fast
 
原文地址:https://www.cnblogs.com/foolangirl/p/14125081.html