给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
数据范围:
,
要求:空间复杂度
,时间复杂度
例如,输入{1,2},{3,4,5}时,对应的环形链表如下图所示:
可以看到环的入口结点的结点值为3,所以返回结点值为3的结点。
输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台会根据第二段是否为空将这两段组装成一个无环或者有环单链表
返回链表的环的入口结点即可,我们后台程序会打印这个结点对应的结点值;若没有,则返回对应编程语言的空结点即可。
{1,2},{3,4,5}3
返回环形链表入口结点,我们后台程序会打印该环形链表入口结点对应的结点值,即3
{1},{}"null"
没有环,返回对应编程语言的空结点,后台程序会打印"null"
{},{2}
2
环的部分只有一个结点,所以返回该环形链表入口结点,后台程序打印该结点对应的结点值,即2
当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。
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; } }