Linked List: Reverse Linked List — Kotlin Solution
Linked List: Reverse Linked List — Kotlin Solution
Problem Info
| LeetCode # | 206 — Reverse Linked List |
| Difficulty | Easy |
| Topic | Linked List, Iteration, Recursion |
Given the head of a singly linked list, reverse the list and return the reversed list.
Example:
1
2
Input: 1 → 2 → 3 → 4 → 5 → null
Output: 5 → 4 → 3 → 2 → 1 → null
The Node Definition
1
2
3
class ListNode(var `val`: Int) {
var next: ListNode? = null
}
Approach
Reversing a linked list means flipping every next pointer to point backward.
You need three references at all times:
prev— the node behind current (starts asnull)curr— the node you’re currently processingnext— save next node before overwritingcurr.next
Walk through 1 → 2 → 3:
1
2
3
4
prev=null, curr=1: save next=2, point 1→null, move prev=1, curr=2
prev=1, curr=2: save next=3, point 2→1, move prev=2, curr=3
prev=2, curr=3: save next=null, point 3→2, move prev=3, curr=null
return prev → 3 → 2 → 1 → null ✓
Kotlin Solution
Approach 1 — Iterative
1
2
3
4
5
6
7
8
9
10
11
12
13
fun reverseList(head: ListNode?): ListNode? {
var prev: ListNode? = null
var curr = head
while (curr != null) {
val next = curr.next // save next before overwriting
curr.next = prev // reverse the pointer
prev = curr // advance prev
curr = next // advance curr
}
return prev // prev is the new head
}
Approach 2 — Recursive
1
2
3
4
5
6
7
8
9
fun reverseList(head: ListNode?): ListNode? {
if (head?.next == null) return head
val newHead = reverseList(head.next)
head.next!!.next = head // reverse the pointer
head.next = null // disconnect old forward link
return newHead
}
Why Kotlin Shines Here
Nullable types built in — no separate null checks needed:
1
2
3
var prev: ListNode? = null
// Kotlin enforces null safety at compile time
// vs Java: no guarantee — NPE risk everywhere
head?.next == null — safe call in one expression:
1
2
if (head?.next == null) return head
// vs Java: if (head == null || head.next == null) return head;
val next = curr.next — val signals this is a one-time save:
1
val next = curr.next // won't be reassigned — intent is clear
Iterative vs Recursive
| Approach | Time | Space | Notes |
|---|---|---|---|
| Iterative | O(n) | O(1) | Preferred — no stack overhead |
| Recursive | O(n) | O(n) | Elegant but risks stack overflow on long lists |
Common Mistake
1
2
3
// ❌ Forgetting to save next before reversing
curr.next = prev // curr.next is now lost forever!
curr = curr.next // this is now prev, not the original next
Always save next first — it’s the very first line inside the loop.
Complexity
| Time | O(n) — visit every node once |
| Space | O(1) iterative / O(n) recursive |
Key Takeaway
Save next, reverse the pointer, advance both pointers. Three lines, three moves — that’s the whole algorithm.
📚 Kotlin DSA Series
This post is part of the Kotlin DSA series — solving LeetCode problems using idiomatic Kotlin.
← View Full Series Index
This post is part of the Kotlin DSA series — solving LeetCode problems using idiomatic Kotlin.
← View Full Series Index
This post is licensed under CC BY 4.0 by the author.