一个链表中包含环,请找出该链表的环的入口结点。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
//分成两步:1.判断是否存在环,并找到快慢两个指针相遇的位置
// 2.根据找到的这个相遇位置,统计环中节点的数目n,先让快指针走n步,然后
// 快慢两个指针一起运动,快慢指针相遇时的节点就是环的入口节点
public ListNode EntryNodeOfLoop(ListNode pHead)
{
//getMeetingNode函数返回null或者环中的一个节点(快慢指针相遇的节点)
ListNode meetNode=getMeetingNode(pHead);
if(meetNode==null){
return null;
}
//根据找到的这个节点统计环中节点的数目
int loopNodes=1;
ListNode cur=meetNode.next;
while(cur!=meetNode){
loopNodes++;
cur=cur.next;
}
//快指针先走loopNodes步
ListNode fast=pHead;
for(int i=1;i<=loopNodes;i++){
fast=fast.next;
}
//慢指针开始跟快指针一起移动
ListNode slow=pHead;
while(slow!=fast){
slow=slow.next;
fast=fast.next;
}
return fast;
}
//先找两个指针相遇的位置
private ListNode getMeetingNode(ListNode pHead){
if(pHead==null){
return null;
}
ListNode slow=pHead.next;
//只有一个结点 ,直接返回null
if(slow==null){
return null;
}
ListNode fast=slow.next;
while(slow!=null&&fast!=null){
if(slow==fast){
return fast;
}
//slow指针在链表上一次移动一步
slow=slow.next;
//fast指针一次在链表上移动两步
fast=fast.next;
if(fast!=null){
fast=fast.next;
}
}
//链表中不存在环,则直接返回null;
return null;
}
}