data-structures · intermediate · ~15 min
Slow/fast two-pointer scan; awareness of the even-length convention.
Find the middle node of a singly-linked list in one pass.
Given the head of a singly-linked list, implement node_t *list_middle(node_t *head) that returns the middle node. For an even-length list, return the node in the second half (for [1,2,3,4], return the node holding 3). The node type is given:
typedef struct node { int v; struct node *next; } node_t;
head: a pointer to the first node (the type node_t is given, with an int v and a next pointer). May be NULL.
node_t *: a pointer to the middle node, or NULL if the list is empty.
[1, 2, 3, 4, 5] -> node(3)
[1, 2, 3, 4] -> node(3) (even length: the second of the two middles)
[1] -> node(1)
[1, 2] -> node(2)
NULL -> NULL
NULL head returns NULL.The two-pointer 'slow/fast' technique is one of the most useful patterns in linked-list problems. Used for cycle detection, splitting in half, palindrome checking — and here, finding the middle in one pass without computing the length first.
head: pointer to the first node_t (given: int v; node_t *next;); may be NULL.
node_t *: pointer to the middle node, or NULL if empty.
Single pass. O(1) extra memory.
typedef struct node { int v; struct node *next; } node_t;
node_t *list_middle(node_t *head) { /* TODO */ return NULL; }
Counting the length first and then walking n/2 — two passes, not one. Returning the first middle on even lengths (not the convention here).
NULL head; one-node list; two-node list; even and odd lengths.
O(n).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.