链表中环的入口结点_55

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

第一种解法:
利用set存储每个结点,如果出现过则返回该结点,如果遍历完了都没找到则返回null

第二种解法:
双指针法:
定义两个指针,一个一次走两步的快指针一个慢指针,如果有环存在,则他们一定会在环上某个结点相遇.这时候他们都开始每次都一步,则下次相遇的点一定是环入口结点.

思路2证明

两个结论:

1、设置快慢指针,假如有环,他们最后一定相遇。

2、两个指针分别从链表头和相遇点继续出发,每次走一步,最后一定相遇与环入口。
思路2证明如下
证明结论1:设置快慢指针fast和low,fast每次走两步,low每次走一步。假如有环,两者一定会相遇(因为low一旦进环,可看作fast在后面追赶low的过程,每次两者都接近一步,最后一定能追上)。

代码:


    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        
        //找出环中相遇的点
        ListNode p1=pHead; //每次走一步的结点
        ListNode p2=pHead;//每次走两步的结点
        ListNode pmeet=null;
        while (p2!=null&&p2.next!=null){ //p2比p1跑的快,如果没有环的话p2先挂掉,所以只判断p2就可以了
             
            p1=p1.next;
            p2=p2.next.next;
            if (p1==p2){
                pmeet=p1;
                break;
            }
        }
        if (pmeet==null){//没环,没有相遇
            return null;
        }
        //如果有环.p1从头走,p2从相遇结点走,下一次相遇就是那个环结点.
        p1=pHead;
        p2=pmeet;
        while (p1!=p2){
            p1=p1.next;
            p2=p2.next;
        }
        return p1;
    }

你可能感兴趣的:(链表中环的入口结点_55)