剑指Offer_编程题55:链表中环的入口结点

题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出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

猜你喜欢

转载自blog.csdn.net/mengmengdajuanjuan/article/details/81260340