这道题的思路如下:
特殊情况:
1、头节点为空,或者只有头节点,则返回null,不存在环(鲁棒性,考虑清楚特殊情况)
常规情况:
1、首先判断有无环:通过两个速度不一样的指针同时从头开始走,快指针一次走两步,慢指针一次走一步,如果存在环,快指针一定会赶上慢指针; 当它们不为空,且相同的时候,说明它们在环中相遇了。
2、判断环中有多少个节点:当从上述步骤走完的时候,快指针和慢指针在环中相遇,这时候我们让快指针继续每次移动一格,计数,当它走到跟慢指针相同的位置的时候,我们就可以得出环中的节点个数:n
3、快指针和慢指针重新从头指针出发,快指针先走n步; 然后两个指针一起走,相遇的时候就到了环中的节点。
/**
* 链表中环的入口节点
*/
public class Main23 {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
if (pHead == null || pHead.next == null){
return null;
}
//用两个速度不一样的指针判断是否存在环
//指针速度一个快,一个慢
ListNode fast = pHead.next.next;
ListNode slow = pHead;
boolean ifHuan = false;
while (fast != null && slow != null && fast != slow){
if (fast == slow){
ifHuan = true;
break;
}
fast = fast.next.next;
slow = slow.next;
}
//如果因为指针为空跳出上面的循环,说明不存在环,则返回结果
if (slow == null){
return null;
}
// slow = pHead;
//求环中节点的个数 n
int n = 1;
while (fast.next != slow){
n++;
fast = fast.next;
}
//用快指针先走n步,然后慢指针从头开始,两个指针一起走,相遇的时候就到了环入口
fast = pHead;
slow = pHead;
while (n > 0){
fast = fast.next;
n--;
}
//两指针开始一起走
while (fast != slow){
fast = fast.next;
slow = slow.next;
}
//相同的时候,即走到了环的入口
return fast;
}
}