Advertisement

Linked List Cycle II - LeetCode 142 Solution

Linked List Cycle II - Complete Solution Guide

Linked List Cycle II is LeetCode problem 142, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem 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. Internally, pos is used to denote the index of the node that tail's next pointer is connected to ( 0-indexed ). It is -1 if there is no cycle. Note that pos is not passed as a parameter . Do not modify the linked list. Example 1: Input: head = [3,2,0,-4

Detailed Explanation

The problem asks us to detect if a cycle exists in a given linked list and, if so, to find the node where the cycle begins. A cycle means that at some point, following the `next` pointers leads back to a previously visited node, forming a loop. The input is the `head` of the linked list. The output is the node where the cycle begins, or `null` (or `nullptr` or `NULL` depending on the language) if no cycle exists. We are not given the position of the cycle's start, and we cannot modify the linked list. The challenge is to solve this in O(1) space.

Solution Approach

The solution uses Floyd's Cycle-Finding Algorithm, also known as the 'tortoise and hare' algorithm. First, we use two pointers, `slow` and `fast`, initialized to the `head` of the list. The `slow` pointer moves one node at a time, while the `fast` pointer moves two nodes at a time. If there is a cycle, the `fast` pointer will eventually catch up with the `slow` pointer. Once they meet, we reset one of the pointers (usually `ptr`) to the `head` of the list. Then, we move both `ptr` and `slow` one node at a time until they meet again. The node where they meet is the starting node of the cycle.

Step-by-Step Algorithm

  1. Step 1: Initialize two pointers, `slow` and `fast`, both pointing to the `head` of the linked list.
  2. Step 2: Iterate through the linked list using a `while` loop as long as `fast` and `fast.next` are not `null` (to avoid NullPointerExceptions).
  3. Step 3: Inside the loop, move `slow` one step forward (`slow = slow.next`) and `fast` two steps forward (`fast = fast.next.next`).
  4. Step 4: Check if `slow` and `fast` are equal. If they are, it means a cycle exists. Break out of the outer `while` loop.
  5. Step 5: If the outer `while` loop completes without `slow` and `fast` meeting, it means there is no cycle. Return `null`.
  6. Step 6: If a cycle exists, initialize another pointer `ptr` to the `head` of the linked list.
  7. Step 7: Move `ptr` and `slow` one step at a time until they meet (`ptr = ptr.next` and `slow = slow.next`).
  8. Step 8: The node where `ptr` and `slow` meet is the starting node of the cycle. Return `ptr`.

Key Insights

  • Insight 1: The 'fast and slow pointer' technique (Floyd's Cycle-Finding Algorithm) is essential for detecting cycles in a linked list without using extra space. If a cycle exists, the fast pointer will eventually catch up to the slow pointer.
  • Insight 2: The distance from the head of the list to the cycle's starting node is equal to the distance from the meeting point of the fast and slow pointers to the cycle's starting node.
  • Insight 3: Correctly handling edge cases such as an empty list or a list without a cycle is crucial for a robust solution.

Complexity Analysis

Time Complexity: O(n)

Space Complexity: O(1)

Topics

This problem involves: Hash Table, Linked List, Two Pointers.

Companies

Asked at: Paytm, Ripple, TikTok.