data-structures · intermediate · ~25 min
Floyd's tortoise-and-hare algorithm (two pointers, different speeds).
Detect whether a singly-linked list contains a cycle.
Given the head of a singly-linked list whose nodes are typedef struct node { int v; struct node *next; } node_t;, implement int has_cycle(node_t *head) that returns 1 if following next pointers ever loops back into a node already visited, else 0.
head: a pointer to the first node (the type node_t is given, with an int v and a next pointer). May be NULL.
int: 1 if the list has a cycle, 0 if it ends at NULL.
1 -> 2 -> 3 -> 4 -> NULL -> 0
1 -> 2 -> 3 -> 4 -> back to 2 -> 1
NULL -> 0
node whose next points to itself -> 1
NULL head returns 0.next == NULL returns 0; a single node pointing to itself returns 1.malloc, do not mutate the list.Floyd's tortoise-and-hare is the canonical example of using rates to find structure: it's used to detect cycles in CPU instruction traces, in random number generators, and in serialization graphs.
head: pointer to the first node_t (given: int v; node_t *next;); may be NULL.
int: 1 if a cycle exists, else 0.
O(1) auxiliary memory. No malloc. No mutating the list.
typedef struct node { int v; struct node *next; } node_t;
int has_cycle(node_t *head) { /* TODO */ return 0; }
Comparing slow != fast before stepping (causes false positive when head==head); not checking fast->next before stepping fast twice (NPE on linear lists); using a hash set when O(1) memory is required.
NULL head. Single node, no cycle. Single node, self-loop. Two-node cycle.
O(n) time, O(1) memory.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.