思路:类似于求链表的倒数第K的节点,使用两个指针p1,p2。使p2先向后移动环的长度个节点,然后两个指针一起向后移动,当p1移动到入口时,p2也移动到入口。如何求出环的长度呢?从判断两个链表有环这个问题中我们可以得到链表环中一个节点,从此节点出发当再次回到此节点时,即得到长度。
/**
* Created by lrx on 2017/4/4.
*/
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
// 找到有环链表的入口节点
public class EntryNodeOfLoop {
private static int getLength(ListNode head) {
ListNode p1,p2;
// 先各自走一下
p1 = head.next;
if (p1 != null)
p2 = p1.next;
else {
return -1;
}
while(p2 != null && p1.val != p2.val) {
p1 = p1.next;
if (p2.next != null)
p2 = p2.next.next;
else
p2 = null;
}
if (p2 == null) return -1;
int length = 1;
p2 = p2.next;
while (p2.val != p1.val) {
p2 = p2.next;
length++;
}
return length;
}
public static ListNode entryNodeOfLoop(ListNode pHead)
{
if (pHead == null) return null;
int length = getLength(pHead);
// 无环链表
if (length == -1) return null;
ListNode p1 = pHead,p2 = pHead;
// p2先向后移动环的长度
for (int i=0; i<length; i++) {
p2 = p2.next;
}
while(p1.val != p2.val) {
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
public static void main(String[] args) {
entryNodeOfLoop(new ListNode(1));
}
}