题目:一个链表中包含环,如何找出环的入口结点?
分析:可设置两个指针p1和p2,初始化时都指向链表头结点,设环中有n个结点,p1先在链表上前进n步,接下来两个指针以相同速度在链表上向前移动,直到它们相遇,则相遇点正好是环的入口结点。如何求n?判断链表是否有环时用到了一快一慢指针,若两个指针相遇,则链表中存在环,且相遇点一定在环中,可以从该结点出发,一边继续向前移动一边计数,当再次回到这个结点时,就可以得到环中结点数。
public class wr56entryNodeLoop {
// 快慢两个指针,得到相遇的点
public ListNode MeetingNode(ListNode pHead){
if(pHead==null){
return null;
}
ListNode fast=pHead;
ListNode slow=pHead;
while(fast!=null && fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
return fast;
}
}
return null;
}
// 找出环中的结点数目,p1先移动环结点数,然后两个指针同速移动,相遇的结点正好是环的入口结点
public ListNode EntryNodeOfLoop(ListNode pHead){
ListNode meetNode=MeetingNode(pHead);
if(meetNode==null){
return null;
}
int nodesInLoop=1;
ListNode p1=meetNode;
while(p1.next!=meetNode){
p1=p1.next;
nodesInLoop++;
}
p1=pHead;
for(int i=0;i<nodesInLoop;i++){
p1=p1.next;
}
ListNode p2=pHead;
while(p1!=p2){
p1=p1.next;
p2=p2.next;
}
return p1;
}
}