Linked List Cycle
Clarify the problem:
- The problem requires determining whether a linked list contains a cycle.
- We need to identify if there is a cycle in the linked list and return a boolean value indicating the presence or absence of a cycle.
Analyze the problem:
- Input: The head node of a linked list.
- Output: A boolean value indicating whether there is a cycle in the linked list.
- Constraints:
- The linked list may be empty.
- The linked list may contain any number of nodes.
- The nodes in the linked list may have arbitrary values.
- The linked list may have a cycle, where a node points to a previously visited node, creating a loop.
Design an algorithm:
- We can use the Floyd's Tortoise and Hare algorithm to determine if there is a cycle in the linked list.
- The algorithm uses two pointers, one moving at a slower pace (tortoise) and the other at a faster pace (hare).
- If there is a cycle, the hare will eventually catch up to the tortoise, indicating the presence of a cycle.
- We can start with both pointers at the head of the linked list and move them accordingly.
- The hare pointer will move two steps at a time, while the tortoise pointer will move one step at a time.
- If the hare reaches the end of the linked list (i.e., a null node), there is no cycle.
- If the hare and tortoise meet at any point, there is a cycle in the linked list.
Explain your approach:
- We will implement a function called
hasCyclethat takes the head of a linked list as input and returns a boolean value indicating whether there is a cycle. - We will use two pointers,
tortoiseandhare, initialized at the head of the linked list. - We will iterate through the linked list, moving the
tortoisepointer one step at a time and theharepointer two steps at a time. - If the
harepointer reaches the end of the linked list (i.e., a null node), we will returnFalse, indicating no cycle. - If the
hareandtortoisepointers meet at any point, we will returnTrue, indicating the presence of a cycle.
- We will implement a function called
Write clean and readable code:
pythonclass ListNode: def __init__(self, x): self.val = x self.next = None def hasCycle(head): if not head or not head.next: return False tortoise = head hare = head.next while tortoise != hare: if not hare or not hare.next: return False tortoise = tortoise.next hare = hare.next.next return TrueTest your code:
- To test the code, we can create a linked list with or without a cycle and call the
hasCyclefunction on it. - Test case 1: No cycle
python- To test the code, we can create a linked list with or without a cycle and call the
- Test case 2: Cycle
# Linked list: 1 -> 2 -> 3 -> 4 -> 2 (points back to the second node) head = ListNode(1) head.next = ListNode(2) head.next.next = ListNode(3) head.next.next.next = ListNode(4) head.next.next.next.next = head.next print(hasCycle(head)) # Output: TrueOptimize if necessary:
- The Floyd's Tortoise and Hare algorithm has an optimal time complexity of O(n) and a space complexity of O(1), where n is the number of nodes in the linked list.
- The algorithm detects the cycle efficiently by traversing the linked list using two pointers, without requiring any additional data structures.
Handle error cases:
- We handle the case when the linked list is empty by checking if the head node is
Noneor if the head node has no next node. - In such cases, we return
Falseto indicate no cycle.
- We handle the case when the linked list is empty by checking if the head node is
Discuss complexity analysis:
- Time complexity: The algorithm has a time complexity of O(n), where n is the number of nodes in the linked list. This is because both pointers traverse the linked list at different speeds, with the faster pointer covering the distance twice as fast as the slower pointer.
- Space complexity: The algorithm has a space complexity of O(1) as it uses only a constant amount of additional space to store the two pointers. It does not require any additional data structures proportional to the size of the input.
# Linked list: 1 -> 2 -> 3 -> 4 -> None
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = ListNode(4)
print(hasCycle(head)) # Output: False
python