Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
To represent a cycle in the given linked list, we use an integer pos
which represents the position (0-indexed) in the linked list where tail connects to. If pos
is -1
, then there is no cycle in the linked list.
Note: Do not modify the linked list.
Example 1:
Input: head = [3,2,0,-4], pos = 1 Output: tail connects to node index 1 Explanation: There is a cycle in the linked list, where tail connects to the second node.
Example 2:
Input: head = [1,2], pos = 0 Output: tail connects to node index 0 Explanation: There is a cycle in the linked list, where tail connects to the first node.
Example 3:
Input: head = [1], pos = -1 Output: no cycle Explanation: There is no cycle in the linked list.
Follow-up:
Can you solve it without using extra space?
单链表中的环二。题意是给一个链表,如果这个链表中有环,请return环的起点;若没有,return null。找是否有环可以参照[LeetCode] 141. Linked List Cycle的讲解。至于怎么找到环的起点,我这里引用一个非常好的讲解,https://www.cnblogs.com/hiddenfox/p/3408931.html
因为快慢指针的速度是一个2步一个1步,所以当两个指针相遇的时候,fast走过的长度一定是slow的两倍。两者相遇的地方一定是环的起点。至于证明,直接参照引用贴。
时间O(n)
空间O(1)
JavaScript实现
1 /** 2 * @param {ListNode} head 3 * @return {ListNode} 4 */ 5 var detectCycle = function(head) { 6 // corner case 7 if (head === null || head.next === null) { 8 return null; 9 } 10 11 // normal case 12 let slow = head; 13 let fast = head; 14 while (fast !== null && fast.next !== null) { 15 slow = slow.next; 16 fast = fast.next.next; 17 if (fast === slow) { 18 let slow2 = head; 19 while (slow !== slow2) { 20 slow = slow.next; 21 slow2 = slow2.next; 22 } 23 return slow; 24 } 25 } 26 return null; 27 };
Java实现
1 /** 2 * Definition for singly-linked list. 3 * class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { 7 * val = x; 8 * next = null; 9 * } 10 * } 11 */ 12 public class Solution { 13 public ListNode detectCycle(ListNode head) { 14 // corner case 15 if (head == null || head.next == null) { 16 return null; 17 } 18 19 // normal case 20 ListNode slow = head; 21 ListNode fast = head; 22 while (fast != null && fast.next != null) { 23 slow = slow.next; 24 fast = fast.next.next; 25 if (slow == fast) { 26 ListNode slow2 = head; 27 while (slow != slow2) { 28 slow = slow.next; 29 slow2 = slow2.next; 30 } 31 return slow; 32 } 33 } 34 return null; 35 } 36 }