Detect and Break a Cycle in a Singly Linked List
Company: Amazon
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question tests practical knowledge of linked list traversal and pointer manipulation, specifically the ability to detect and resolve cycles using space-efficient algorithms. It evaluates algorithmic reasoning and low-level data structure skills commonly assessed in software engineering interviews.
Constraints
- 0 <= number of nodes <= 10^5
- Node values fit in a 32-bit integer
- There is at most one cycle
- pos is in [-1, number of nodes - 1]; pos = -1 means no cycle
Examples
Input: ([3, 2, 0, -4], 1)
Expected Output: [True, [3, 2, 0, -4]]
Explanation: -4 (index 3) points back to value 2 (index 1). Floyd detects the cycle; the entry is value 2; the offending node is -4, whose next is reset to NULL. List stays [3,2,0,-4] but is now acyclic.
Input: ([1, 2], 0)
Expected Output: [True, [1, 2]]
Explanation: Node 2 points back to node 1 (the head). Entry is the head; the offending node is 2; its next becomes NULL.
Input: ([1, 2, 3], -1)
Expected Output: [False, [1, 2, 3]]
Explanation: No cycle: fast pointer reaches NULL, so found is false and the list is returned unchanged.
Input: ([], -1)
Expected Output: [False, []]
Explanation: Empty list edge case — head is NULL, the loop never runs, no cycle.
Input: ([7], 0)
Expected Output: [True, [7]]
Explanation: Single node self-loop (its next points to itself). Floyd still detects it via fast.next; the entry and offending node are the same node, whose next is reset to NULL.
Input: ([7], -1)
Expected Output: [False, [7]]
Explanation: Single node, no cycle — found is false, list unchanged.
Input: ([5, 5, 5, 5, 5], 2)
Expected Output: [True, [5, 5, 5, 5, 5]]
Explanation: Duplicate values must not confuse detection — identity (node references), not value equality, drives the algorithm. The cycle from the tail back to index 2 is detected and broken.
Input: ([-1, -2, -3, -4, -5, -6], 0)
Expected Output: [True, [-1, -2, -3, -4, -5, -6]]
Explanation: Negative values and a full-list cycle (tail back to head). Entry is the head; offending node is the last node.
Input: ([10, 20, 30, 40, 50], 4)
Expected Output: [True, [10, 20, 30, 40, 50]]
Explanation: Self-loop on the last node only (tail points to itself, pos=4). A minimal one-node cycle at the tail; it is detected and broken without touching earlier nodes.
Hints
- Use Floyd's tortoise-and-hare: a slow pointer (1 step) and a fast pointer (2 steps). If they ever meet, there is a cycle; if fast reaches NULL, there is not.
- After the meeting point is found, reset one pointer to head and advance both one step at a time. They meet again exactly at the cycle entry — this is the classic distance-equality argument (head-to-entry distance equals meeting-point-to-entry distance around the loop).
- The offending node is the node *just before* the entry along the loop — i.e. walk from the entry around the cycle until you find the node whose `next` is the entry, then set that `next` to NULL. Do not touch any other pointer or any value.