自己根据列表写的,比较简单。
# -*- 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;
}
}