49. Linked List Cycle
Problem Statement
Given head
, the head of a linked list, determine if the linked list has a cycle in it.
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
pointers. Internally, pos
is used to denote the index of the node that tail's next
pointer is connected to. Note that pos
is not passed as a parameter.
Return true
if there is a cycle in the linked list. Otherwise, return false
.
Example 1:
Input: head = [3,2,0,-4], pos = 1 Output: true Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).
Example 2:
Input: head = [1,2], pos = 0 Output: true Explanation: There is a cycle in the linked list, where the tail connects to the 0th node.
Example 3:
Input: head = [1], pos = -1 Output: false Explanation: There is no cycle in the linked list.
Solution
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head or not head.next:
return False
slow = head
fast = head.next
while fast and fast.next:
if slow == fast:
return True
slow = slow.next
fast = fast.next.next
return False
Explanation
This problem is a classic application of the Floyd's Cycle-Finding Algorithm, also known as the "tortoise and hare" algorithm.
Core Idea: If there is a cycle in a linked list, a fast pointer will eventually catch up to a slow pointer if they both start at the beginning and the fast pointer moves twice as fast as the slow pointer.
-
Initialize Pointers:
slow
pointer starts athead
.fast
pointer starts athead.next
(orhead
, buthead.next
is often used to ensurefast
is ahead initially).
-
Traverse the List: We iterate using a
while
loop as long asfast
andfast.next
are notNone
. This ensures we don't run into an error if the list ends.- In each step,
slow
moves one step (slow = slow.next
). fast
moves two steps (fast = fast.next.next
).
- In each step,
-
Cycle Detection:
- If at any point
slow
andfast
pointers meet (i.e.,slow == fast
), it means there is a cycle in the linked list, and we returnTrue
.
- If at any point
-
No Cycle: If the loop finishes (meaning
fast
orfast.next
becameNone
), it implies thatfast
reached the end of the list without meetingslow
. This indicates there is no cycle, and we returnFalse
.
Time and Space Complexity:
- Time Complexity: O(N), where N is the number of nodes in the linked list. In the worst case (no cycle or cycle at the very end), the fast pointer traverses the entire list. If there is a cycle, the fast pointer will eventually catch the slow pointer within the cycle.
- Space Complexity: O(1), as we only use a few extra pointers.