php实现找链表中环的入口节点(画图、看评论)
php实现找链表中环的入口节点(画图、看评论)
一、总结
画图、看评论
二、php实现找链表中环的入口节点
题目描述:
一个链表中包含环,请找出该链表的环的入口结点。
三、代码
- 第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。
- 第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,设环中有n个节点,p2比p1多走一圈有2x=n+x; n=x;可以看出p1实际走了一个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。
不严谨,如果环比较小,在慢针没入环的时候,快针可能已经转了N久了
设起点到相遇点距离为x,起点到入口点距离为y,环长度为r,则快慢针相遇时,满足2x-x=nr,n为快针在环中转的圈数。--> x=nr
快慢针相遇点距环入口点距离x-y
相遇后,快针从起点重新开始以步长为1速度开始走,经过距离y到达环入口点,慢针走y步后距离环入口点距离为x-y+y=x=nr,即走到了环入口点,两个指针相遇
代码没有问题,但是数学证明不严谨
我来说明一下多走k圈和1圈其实是一样的:根据题目要求,找入口结点就相当于找倒数第n个结点,而倒数第kn个结点其实就是倒数第n个结点。所以这个题就变成找倒数第kn个结点,刚好p1已经走了kn个结点,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。
这就说明不管是1圈还是k圈,结果是一样的,可以直接看成一圈来解答。
多走k圈和多走一圈是一样的,a是头结点到入口结点的距离,b是入口节点Y到相遇处Z的距离,c是环的长度减去b。
相遇时有:
S_{fast} = 2S_{slow}
假设相遇时pFast在环内转了k圈,则
a + k(b+c) + b = 2(a + b)
移项得:
a = (k-1)(b+c) + c
说明头结点X到入口结点Y的距离等于从相遇处Z开始在环内转悠k-1圈(k >= 1)后,最后从Z到Y的距离。当k =1时候,a = c,此时pFast比pSlow多走一圈(也就是大家一直讨论的情况)
1 public class Solution { 2 3 ListNode EntryNodeOfLoop(ListNode pHead){ 4 if(pHead == null || pHead.next == null) 5 return null; 6 ListNode p1 = pHead; 7 ListNode p2 = pHead; 8 while(p2 != null && p2.next != null ){ 9 p1 = p1.next; 10 p2 = p2.next.next; 11 if(p1 == p2){ 12 p2 = pHead; 13 while(p1 != p2){ 14 p1 = p1.next; 15 p2 = p2.next; 16 } 17 if(p1 == p2) 18 return p1; 19 } 20 } 21 return null; 22 } 23 }
版权申明:欢迎转载,但请注明出处
一些博文中有一些参考内容因时间久远找不到来源了没有注明,如果侵权请联系我删除。
在校每年国奖、每年专业第一,加拿大留学,先后工作于华东师范大学和香港教育大学。
2024-10-30:27岁,宅加太忙,特此在网上找女朋友,坐标上海,非诚勿扰,vx:fan404006308
AI交流资料群:753014672