【打卡】牛客网:BM7 链表中环的入口结点

自己根据列表写的,比较简单。 

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

                return pHead  # print(pHead.val) 没看清楚题目啊,是返回不是输出。
            mylist.append(pHead)
            pHead = pHead.next

        return None  # print("null")

看评论中有更加复杂的方法,使用了快慢指针。(不明白为什么要走a步

class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
 
        fast = pHead
        slow = pHead
        while fast:
            if not fast.next: 
                return None 
                # 快指针下一步不能走说明没有环
                # 这里判断换成if not fast: 不行!因为有示例三的情况
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                # 两指针相遇
                fast = pHead
                # 让快指针指向头节点
                while fast != slow:
                    fast = fast.next
                    slow = slow.next
                    # 走a步(环之前步数)
                return fast
        return None

 关于走a步的问题,咨询了一位大佬:

评论区回复最高的写的:如果链表中有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。所以首先要得到环中结点的数目。(没有看。个人看法,好像没有必要非要把环中的节点个数算出来把,知道相遇就可以了?

public class 链表中环的入口结点 {
	//找到一快一满指针相遇处的节点,相遇的节点一定是在环中
	public static ListNode meetingNode(ListNode head) {
		if(head==null)
			return null;
		
        ListNode slow = head.next;
        if(slow==null)
        	return null;
        
        ListNode fast = slow.next;
        while (slow != null && fast != null) {
        	if(slow==fast){
        		return fast;
        	}
        	slow=slow.next;
        	fast=fast.next;
        	
        	if(fast!=slow){
        		fast=fast.next;
        	}
        }
		return null;
    }
	public ListNode EntryNodeOfLoop(ListNode pHead) {
		ListNode meetingNode=meetingNode(pHead);
		if(meetingNode==null)
			return null;
//		得到环中的节点个数
		int nodesInLoop=1;
		ListNode p1=meetingNode;
		while(p1.next!=meetingNode){
			p1=p1.next;
			++nodesInLoop;
		}
//		移动p1
		p1=pHead;
		for(int i=0;i<nodesInLoop;i++){
			p1=p1.next;
		}
//		移动p1,p2
		ListNode p2=pHead;
		while(p1!=p2){
			p1=p1.next;
			p2=p2.next;
		}
		return p1;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值