Linked List Cycle

 

  1. 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.
  2. 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.
  3. 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.
  4. Explain your approach:

    • We will implement a function called hasCycle that 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, tortoise and hare, initialized at the head of the linked list.
    • We will iterate through the linked list, moving the tortoise pointer one step at a time and the hare pointer two steps at a time.
    • If the hare pointer reaches the end of the linked list (i.e., a null node), we will return False, indicating no cycle.
    • If the hare and tortoise pointers meet at any point, we will return True, indicating the presence of a cycle.
  5. Write clean and readable code:

    python
  6. class 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 True
  7. Test your code:

    • To test the code, we can create a linked list with or without a cycle and call the hasCycle function on it.
    • Test case 1: No cycle
    python
  8. # 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
    • Test case 2: Cycle
    python
  9. # 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: True
  10. Optimize 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.
  11. Handle error cases:

    • We handle the case when the linked list is empty by checking if the head node is None or if the head node has no next node.
    • In such cases, we return False to indicate no cycle.
  12. 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.
Next Post Previous Post