1、题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
2、思路
(1)确定链表中是否包含环
定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步,如果走得快的指针追上了走的慢的指针,那么链表就包含环;如果走的快的指针走到了链表的末尾都没有追上走的慢的指针,那么链表就不包含环。
(2)确定环中节点的个数
在(1)中,快慢两个指针相遇时,一定是在环中。可以使慢指针向前移动,快指针不动,当两个节点再次重合时,便可以得到环中节点的数量。
(3)确定环的入口节点
设置两个指针分别指向链表的头结点,假设环中的节点数量是count,一个指针先走count步,然后两个指针一起走,当两个指针重合时,所指向的节点便是环的入口节点。
3、代码实现
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
if(pHead == null){
return null;
}
ListNode fast = pHead;
ListNode slow = pHead;
boolean hav = false;
//统计链表中是否有环
while(fast != null){
slow = slow.next;
fast = fast.next;
if(fast!=null){
fast = fast.next;
}
if(fast == slow && fast!=null){
hav = true;
break;
}
}
int count = 1;
ListNode node1 = pHead;
ListNode node2 = pHead;
if(hav){
slow = slow.next;
//统计环中的节点数量
while(slow != fast && slow!=null ){
slow = slow.next;
count++;
}
//设置两个指向头结点的指针,让第一个指针先走count步,然后两个指针一起走
//当两个指针所指的节点相等时,该节点便是入口节点。
for(int i=0;i<count;i++){
node1 = node1.next;
}
while(node1 != node2 ){
node1 = node1.next;
node2 = node2.next;
}
return node1;
}else{
return null;
}
}
}