如何找到带环链表的入口节点?

2种思路:
首先我们假设有个带环链表list1,如图我们可以这么做:
这里写图片描述
这样问题就转换成了如何求出2个不带环链表的相交节点

很明显你会问如何在环中找到一个节点,你不可能去遍历(会死循环),有这样一个办法,我们设置一个快慢指针first,second,快指针一次走2个节点,慢指针一次走一个节点,那么它们最终在环内相遇。

你会问:如果快指针每次都跳过慢指针那?
当然不会。
证明如下:
我们可以利用反证法:假设快指针会跳过慢指针

假设在一次移动后在first在second的前一个点,即first跳过second,那么我们使first,second各向后移动一次,first与second重合,即它们在之前已经相遇,原命题错误。

那我们可以写出这段代码:

       ListNode *first  = pHead;
       ListNode *second = pHead;
        //判断条件是为了判断链表是否带环
        while ( first && first->next != NULL ){

            first = first->next->next;
            second = second->next;
            if ( second == first ){

                break;
            }

        }

找到这个点之后,我们就可以把原链表断开
对于怎么找到2个不带环链表的思路,为了简便,我把我的另一条链接贴在这吧:http://blog.csdn.net/fengasdfgh/article/details/52900963

现在,我们来说第二种方法:
我们在第一种解法中找到了一个环内节点 f ,第二种思路是再让一个指针third指向头结点,让third与 f 同速度往前走,它们相等的点即为入口节点。

证明如下:
这里写图片描述
这里写图片描述

展开阅读全文
博主设置当前文章不允许评论。

没有更多推荐了,返回首页