Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Walk a pointer from head to null, printing each node's value on its own line as you go. One while-loop, O(n) time, O(1) space. The only trap is the loop guard: stop when the pointer is null, and advance the pointer every iteration so you don't loop forever.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you can write a clean traversal loop with the correct termination condition, advance the pointer every iteration, and not clobber the head reference.
Where candidates slip
Looping on `while cur.next` (drops the last node), forgetting `cur = cur.next` (infinite loop), or walking `head` directly so the list reference is lost.
How to stand out
State that it's O(n) time / O(1) space, that the empty list needs no special case, and that this loop is the template you'll reuse for count, search, and reverse.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachFirst decision previewcur = headcur != null?NoYesExplore the full treeCollapse the tree
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 1 · Optimal
Iterative Traversal (Optimal)
1Hint 1Explore hintHide hint
You need to touch every node exactly once. What's the loop that walks a singly linked list from front to back?
2Hint 2Explore hintHide hint
Keep a pointer starting at head. While it isn't null, print its value, then move it to the next node.
3Hint 3Explore hintHide hint
What is the loop condition that includes the very last node but stops after it — `cur != null` or `cur.next != null`?
A · Core idea
Start a pointer cur at the head. While cur is not null, print cur.val, then advance cur = cur.next. When cur becomes null we've walked off the end and the loop stops.
Why the guard is `cur != null`, not `cur.next != null`. We want to print the current node, including the last one. The last node has next == null but is itself non-null, so cur != null prints it and then the advance makes cur null and ends the loop. If you guard on cur.next != null, the loop exits one node early and the tail never prints.
Why advance every iteration. The line cur = cur.next is what makes progress. Omit it and cur stays on the head forever — an infinite loop printing the same value. The advance must run on every pass, so it goes at the end of the loop body.
Why a separate pointer. We traverse with cur, not head itself. If you walk head to the end, you've lost your handle on the start of the list. Even though printing doesn't need head afterwards, using a dedicated pointer is the habit that keeps you safe in problems that do.
Why the empty list needs no branch. If head is null, cur starts null, the guard is immediately false, and the body never runs — printing nothing, which is exactly correct.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
list = [16, 13, 7]Array state
print 16
cur on node 16 → print, then advance
16
13
7C · Code with teaching comments
D · Why it works and complexityO(n) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
This loop — initialise cur = head, guard cur != null, body then cur = cur.next — is the universal singly-linked-list traversal template. Counting nodes, summing values, searching for a key, and reversing all start from this exact skeleton; only the body changes.
ComplexityO(n) time, O(1) space — Each of the n nodes is visited and printed exactly once → O(n) time. A single pointer variable, no extra structures → O(1) space.
E · Edge cases and pitfalls6list = [] — cur is null at the start; the loop body never runs; nothing is printed.Explore edge casesHide edge cases
Edge cases handled
list = []cur is null at the start; the loop body never runs; nothing is printed.list = [42]Prints 42, advances cur to null, loop ends. Single node works with no special handling.
Pitfalls
- Looping on `while cur.next != null` — drops the final node.
- Forgetting `cur = cur.next` — infinite loop printing the head forever.
- Walking `head` directly instead of a copy — loses the list reference for any later use.
- Adding a special case for the empty list — the loop already handles it by printing nothing.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic class ListNode { int val; ListNode next; ListNode() {} ListNode(int val) { this.val = val; }Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Wrong loop guard drops the last node
Guarding on cur.next != null stops the loop while cur still points at the final node, so its value never prints. The guard must be on cur itself.
Explore the code comparisonHide the code comparison
Wrong loop guard drops the last node
Guarding on cur.next != null stops the loop while cur still points at the final node, so its value never prints. The guard must be on cur itself.
Don't write this
ListNode cur = head;
while (cur.next != null) { // stops one node too early
System.out.println(cur.val);
cur = cur.next;
}Write this instead
ListNode cur = head;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}2Forgetting to advance the pointer
Without cur = cur.next, the pointer never moves off the head, so the guard stays true forever and the same value prints in an infinite loop.
Explore the code comparisonHide the code comparison
Forgetting to advance the pointer
Without cur = cur.next, the pointer never moves off the head, so the guard stays true forever and the same value prints in an infinite loop.
Don't write this
cur = head
while cur is not None:
print(cur.val)
# missing cur = cur.next -> infinite loopWrite this instead
cur = head
while cur is not None:
print(cur.val)
cur = cur.nextRevise
Carry the pattern into the interview
Pattern to remember
Linear traversal: walk until null, visit each node
Code pattern to memorize
cur = head
while cur is not None:
print(cur.val)
cur = cur.nextRules to remember
- 1Loop while the pointer is not null, not
while cur.next— the latter skips the last node. - 2Advance
cur = cur.nextinside the loop on every iteration, or you spin forever on the head. - 3Use a separate pointer, not
headitself — overwritingheadloses the reference to the list. - 4An empty list (
head == null) prints nothing — the loop body never runs, no special branch needed. - 5Print one value per line, in order from head to tail — don't reverse or collect-then-print unless asked.
Use this pattern when
- You need to visit every node of a singly linked list exactly once
- Reading / emitting list contents in head-to-tail order
- Any base-case linked-list operation: counting, summing, searching, copying
- Warm-up for harder traversals (reverse, cycle detection, merge)
Choose another pattern when
- You need the nodes in reverse order → reverse first, or recurse and print on the way back up
- You must stop early at a condition → add the condition to the loop guard, don't print everything
- You need random access by index → linked lists are O(n) per access; consider an array
Interview takeaway
The walk-until-null loop is the skeleton of every linked-list algorithm. Master the loop guard (`cur != null`) and the advance step (`cur = cur.next`), and harder problems become variations on this one shape.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternThe canonical singly-linked-list traversal: cur = head, while cur != null, advance cur = cur.next. Every count, search, sum, and reverse problem starts from this exact loop.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Count the NodesComing soonSame loop, but increment a counter in the body instead of printing.
- Reverse Linked ListTraverse with the same skeleton but rewire next pointers as you go.
- Reverse Print a Linked ListComing soonRecurse to the tail, then print on the way back up — or push onto a stack and pop.