链表中环的入口

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)//求环入口,先找到环的长度,再让一个指针走环长度步,再让另一个指针之后开始走,两者相遇的地方就是环入口
    {
        ListNode meetingNode=MeetingNode(pHead);
        if(meetingNode==null)
            return null;
        //得到环中节点的数目
        int nodesInLoop=1;
        ListNode pNode1=meetingNode;
        while(pNode1.next!=meetingNode)
        {
            pNode1=pNode1.next;
            ++nodesInLoop;
        }
        //先移动pNode1,次数为环中节点的数目
        pNode1=pHead;
        for(int i=0;i<nodesInLoop;++i)
            pNode1=pNode1.next;
        
        ListNode pNode2=pHead;
        while(pNode1!=pNode2){
            pNode1=pNode1.next;
            pNode2=pNode2.next;
        }
        return pNode1;
    }

    ListNode MeetingNode(ListNode pHead)//通过快慢指针,找还上上的相遇点,因为有环肯定会相遇,没环肯定不会相遇
    {
        if(pHead==null)
            return null;
        ListNode pSlow=pHead.next;
        if(pSlow ==null)
            return null;
        ListNode pFast=pSlow.next;
        while(pFast!=null&&pSlow!=null)
        {
            if(pFast==pSlow)
                return pFast;
            pSlow=pSlow.next;
            pFast=pFast.next;
            if(pFast!=null)
                pFast=pFast.next;
        }
        return null;
    }
}

猜你喜欢

转载自www.cnblogs.com/nickup/p/9749763.html