问题描述
给定一个有环链表,实现一个算法返回环路的开头节点。
有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。
示例 1:
输入:head = [1,2,3,4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [5,3], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [3], pos = -1
输出:no cycle
解释:链表中没有环。
要求空间复杂度为o(1)
算法实现
/**
* Definition for singly-linked list.
* 1. 先通过快慢指针,求得相遇点(fast指针速度是slow的2倍)
* 2. 再将fast指针从head开始,slow指针从相遇点开始,以相同的速度往下走,直到相遇,那么此时的相遇点就是“环路的头结点”
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
//先求相遇点
ListNode fast = head;
ListNode slow = head;
while(fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(slow==fast){
break;
}
}
//如果没有相遇点返回NULL
if(fast==null||fast.next==null){
return null;
}
//将快慢指针中的快指针重置到头部,
//并且与慢指针一起匀速往后奏,相遇点就是入口点
fast = head;
while(fast!=slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}