Find the first point in Linked List with cycle
Level - Medium
Statement
Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.
There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer.
Do not modify the linked list.
Example 1
Input:
Output:
return node "3"
Example 2
Input:
Output:
return null
You can try this at:
Brute Force Approach
- Initialize an empty set or
hash tableto keep track of visited nodes. - Traverse the linked list from the head node.
- For each node, check if it is already in the set. If it is, then it is the starting node of the cycle, so return that node.
- If the current node is not in the set, add it to the set and move to the next node.
- If you reach the end of the linked list without finding a cycle (i.e., a null or None value), return null to indicate that there is no cycle.
Complexity
Time Complexity:
O(N)
Space Complexity:
O(N)
Optimal Approach with constant Space
- Initialize two pointers,
slowandfast, both pointing to the head of the linked list. - Use a while loop to continuously iterate through the linked list until a break condition is met. This loop is used to find the meeting point of the
slowandfastpointers within the cycle.- If either the
fastpointer or its next node is null, return null to indicate no cycle exists. - Move the
slowpointer one step forward. - Move the
fastpointer two steps forward.
- If either the
- Check if the
slowandfastpointers are pointing to the same node. If they are, break out of the loop, as the meeting point within the cycle is found. - After finding the meeting point, reset the
slowpointer back to the head of the linked list. - Use another while loop to iterate through the linked list again. Both the
slowandfastpointers move one step at a time until they meet again.- If the
fastandslowpointers are pointing to the same node, break out of the loop, as the first node of the cycle is found.
- If the
- Return the node where the
slowpointer is currently pointing, which is the first node of the cycle.
Floyd's Tortoise and Hare Algorithm Dry Run(Visual Walkthrough)
Intution Behind Algorithm(Visual Walkthrough)
Implementation
- Java
- CPP
- Python
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(true){
if(fast==null || fast.next==null)return null;// no cycle in linked list
slow = slow.next;
fast = fast.next.next;
if(fast==slow)break; // we get the meeting point
}
slow = head;
while(fast!=slow){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
class Solution {
public:
ListNode* detectCycle(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (true){
if (fast == nullptr || fast->next == nullptr)
return nullptr; // no cycle in linked list
slow = slow->next;
fast = fast->next->next;
if(fast==slow)break;// we get the meeting point
}
slow = head;
while (fast != slow) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow = head
fast = head
while True:
if fast is None or fast.next is None:
return None # no cycle in linked list
slow = slow.next
fast = fast.next.next
if fast == slow:
break
slow = head
while fast != slow:
slow = slow.next
fast = fast.next
return slow
Complexity
Time Complexity:
O(N)
Space Complexity:
O(1)