Introduction Link to heading
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: Link to heading
Can you solve it without using extra space?
Solution Link to heading
Simple solution:
type ListNode struct {
Val int
Next *ListNode
}
func detectCycle(head *ListNode) *ListNode {
if head == nil || head == head.Next {
return head
}
for i, j := one(head), two(head); i != nil && j != nil; i, j = one(i), two(j) {
if i == j {
meet := i
if meet == head {
return meet
}
for i, j := one(meet), one(head); i != nil && j != nil; i, j = one(i), one(j) {
if i == j {
return i
}
}
}
}
return nil
}
func one(node *ListNode) *ListNode {
return node.Next
}
func two(node *ListNode) *ListNode {
next := node.Next
if next == nil {
return nil
} else {
return next.Next
}
}
Explanation Link to heading
First i pointer goes one step a time, whereas second j pointer goes two steps a time.
When they meet, first i pointer will ahead in T+X steps, whereas seconds pointer j will go ahead on N*2 steps.
Second pointer j will definitely do one loop before meeting i, because it is faster, so it will go N+M steps ahead.
At the same time j do two steps in one iteration, therefore N+M, must divide on 2, that gives M=N and N*2 steps for j.
We know that N=T+X, whereas N is the loop size, T is the tail size and X is unknown position where pointers will meet.
By using simple calculous we can find that T=N-X
To find the T in loop, we need to continue going till the end of the loop using pointer i, that will give us N-X steps, and start j pointer from the head, since it will go exactly T steps, they will definitely meet with each other.