题目描述:
标签:链表 双指针
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
代码:
思路分析:这里最重要的是在判断有没有环的情况下加入了数学推导,这真的太难了。
这里借鉴数学推导把,因为判断有环的思路和环形链表(思路见:环形链表)一样。
以及关于为什么是在慢指针slow的第一圈相遇的证明:
1、假设环长n,当慢指针刚开始进入环时,快指针已经走了x了。所以此时慢指针落后于快指针n-x。
2、慢指针在环内的运动速度为1/s,快指针在环内的运行速度为2/s,所以为了追上慢指针,需要(n-x)s秒
3、慢指针在这段时间内运行的距离为(n-x)s*1/s=(n-x)<n,所以可见会在慢指针在环内的第一圈相遇!
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null || head.next == null){
return null;
}
ListNode slow = head;
ListNode fast = head;
do{
if(fast == null || fast.next == null){
return null;
}
slow = slow.next;
fast = fast.next.next;
}while(slow != fast);
ListNode ptr = head;
while(ptr != slow){
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
}