题目
思路
7<-6<- 5
| ^
| |
0->1->2->3->4
[-----]
a
居然不支持图片麻烦死个人了,简单说一下,如上图所示
我们设置快慢两个指针,fast, slow fast一次前进两步,slow一次前进一步,
设a为第一个节点到入环节点的距离。 a=[0->2]
设b为入环口到相遇点的距离。b=[2->6]
设c为相遇点到入环口的距离。c=[6->2]
当fast,和slow相遇的时候,fast经过的节点是slow的两倍,设slow经过的节点数为S
根据上面的设置 可知 S=a+b ,2S=a+b+c+b,可知 a=c,此时让slow回到第一个节点,
fast处于第一次相遇的节点,此时slow从第一个节点出发,因为a=c,所以fast,和slow会在入环口第二次相遇,得到要求的节点。
代码(清晰)
// 步骤一:使用快慢指针判断链表是否有环
ListNode p = head, p2 = head;
boolean hasCycle = false;
while (p2 != null && p2.next != null) {
p = p.next;
p2 = p2.next.next;
if (p == p2) {
hasCycle = true;
break;
}
}
// 步骤二:若有环,找到入环开始的节点
if (hasCycle) {
ListNode q = head;
while (p != q) {
p = p.next;
q = q.next;
}
return q;
} else
return null;
}
}