刷题记录-剑指offer23:链表中环的入口节点

Posted tendermelon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题记录-剑指offer23:链表中环的入口节点相关的知识,希望对你有一定的参考价值。

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

设置快慢指针,都从链表头出发,快指针每次走两步,慢指针一次走一步,假如有环,一定相遇于环中某点。接着让两个指针分别从相遇点和链表头出发,两者都改为每次走一步,最终相遇于环入口。

证明:

技术图片

 

 

 快指针路程=a+(b+c)k+b ,k>=1  其中b+c为环的长度,k为绕环的圈数(k>=1,即最少一圈,不能是0圈,不然和慢指针走的一样长,矛盾)。

慢指针路程=a+b,这里要证明慢指针被追上时一定没有走完一圈,否则慢指针路程就是a+(b+c)m+b。慢指针进圈的时候,和快指针的最大距离是b+c-1,如果在这个距离下,慢指针被追上时都没有走完一圈,那么任何情况下就一定不会。假设从慢指针进圈到被追上经过t秒,它的速度是1,快指针速度是2,那么2t=t+(b+c-1),则t=b+c-1,慢指针走的路没有超过一圈,得证。

public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead == null||pHead.next == null)
            return null;
        ListNode pFast = pHead;
        ListNode pSlow = pHead;
        do{
pFast = pFast.next; //这个地方要注意,要用do,while循环不能用while, if(pFast.next != null){ //因为快慢指针的初始值一样,如果用while(pFast!=pSlow){}, 会一直无法进入循环体 pFast = pFast.next; }else{ return null; } pSlow = pSlow.next; }while(pFast != pSlow); pSlow = pHead; while(pFast != pSlow){ pFast = pFast.next; pSlow = pSlow.next; } return pSlow; } }

 

以上是关于刷题记录-剑指offer23:链表中环的入口节点的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer系列29-----链表中环的入口节点-

剑指Offer对答如流系列 - 链表中环的入口节点

双100%解法LeetCode 141 剑指Offer 23链表中环的入口节点

双100%解法LeetCode 141 剑指Offer 23链表中环的入口节点

剑指 Offer II 022. 链表中环的入口节点

剑指offer 链表中环的入口结点