LenleDaytoy

剑指offer-23.链表中环的入口节点

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

第一步:判断链表是否有环

使用快慢指针法:两个节点从头节点出发,快指针一次走两步,慢指针一次走一步,如果快慢指针相遇,则链表有环

第二步:找入口节点

思路一:使用两个指针,第一个指针位于第一个节点,第二个节点置于快慢节点相遇的地方,两个节点每次走一步,相遇点即环的入口点。

思路二:首先置一个指针于快慢节点相遇处,一边向前走一边计数,当再次回到这个节点,即得到得到环中结点数目。再先定义两个指针P1和P2指向链表的头结点。如果链表中的环有n个结点,指针P1先在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向的入口结点时,第一个指针已经围绕着揍了一圈又回到了入口结点。

1.搬运别人的(推荐这个写法)

 1 class Solution:
 2     def EntryNodeOfLoop(self, pHead):
 3         if pHead==None or pHead.next==None or pHead.next.next==None:
 4             return None
 5         low=pHead.next
 6         fast=pHead.next.next
 7         while low!=fast:
 8             if fast.next==None or fast.next.next==None:  #先判断不为空再赋值
 9                 return None
10             low=low.next
11             fast=fast.next.next
12         fast=pHead
13         while low!=fast:
14             low=low.next
15             fast=fast.next
16         return fast

 

2.第一次自己写的

class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        if not pHead or not pHead.next or not pHead.next.next:
            return None
        fast=pHead.next.next
        slow=pHead.next
        while fast and fast.next:
            if fast==slow:
                p=self.findnode(pHead,fast)
                return p
            fast=fast.next.next
            slow=slow.next
        return None
    def findnode(self,phead,fast):
        p1=fast
        p2=phead
        while p1 and p2:
            if p1==p2:
                return p1
            p1=p1.next
            p2=p2.next
******************下面是配套的代码,可以实际运行,*******************************************
#将数组转化成有环的链表
def arrlist(arr):
    head = ListNode(arr[0])
    cur=ListNode(arr[1])
    head.next=cur
    cur2 = ListNode(arr[2])
    cur.next=cur2
    cur2.next=cur
    return head
if __name__=='__main__':
    a=[4,3,2]
    s=Solution()
    head1=arrlist(a)
    arr=s.EntryNodeOfLoop(head1)
    print(arr.val)   #输出入口节点的值

3.利用列表,将出现过的元素放入列表。

class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        #遍历链表,环的存在,遍历遇见的第一个重复的即为入口节点
        tempList = []
        p = pHead
        if not p:
            return None
        while p:
            if p in tempList:
                return p
            else:
                tempList.append(p)
            p = p.next
        return None

  

  

 

posted on 2020-04-20 21:27  LenleDaytoy  阅读(121)  评论(0编辑  收藏  举报

导航