Reverse Linked List
Problem Description
Reversing a linked list is a very classic interview question. The task is to reverse the order of all nodes in a singly linked list and return the head node of the reversed list. For example, given the linked list 1 -> 2 -> 3 -> 4 -> 5, after reversal it should become 5 -> 4 -> 3 -> 2 -> 1. This problem tests the understanding of the linked list data structure and proficiency in pointer (reference) manipulation.
Solution Process
We will use an iterative approach to solve this problem, which is one of the most intuitive and efficient methods. The entire process can be understood as traversing the linked list while "bending" the direction of each node's pointer to the opposite side.
Core Idea
We need three pointers to work together:
prev: Points to the previous node of the current node (initialized asnull, because after reversal, the original head node will become the tail node, and itsnextshould point tonull).curr: Points to the node currently being processed.next: Temporarily saves the next node of the current node, preventing the linked list from breaking and losing subsequent nodes after modifying the pointer ofcurr.next.
Step-by-Step Breakdown
Suppose we have a linked list: 1 -> 2 -> 3 -> 4 -> 5 -> null. Our goal is to reverse it to 5 -> 4 -> 3 -> 2 -> 1 -> null.
-
Step Zero: Initialization
- Before starting the traversal, we set the
prevpointer tonulland thecurrpointer to the head node of the linked list (i.e., node 1). - Current state:
prev = null,curr = 1. - Linked list:
1 -> 2 -> 3 -> 4 -> 5 -> null
- Before starting the traversal, we set the
-
Step One: Process the first node (node 1)
- Save the next node: First, we need a temporary pointer
nextto save the next node ofcurr, which is node 2.next = curr.next(next = 2). This step is crucial because in the next step we will modifycurr.next. If we don't save it beforehand, we will lose the reference to node 2. - Reverse the pointer: Then, we make the
nextpointer of the current nodecurr(node 1) point to its previous nodeprev(which isnullat this moment). Executecurr.next = prev. Now, node 1 points tonull. The linked list becomes1 -> null, while the part2 -> 3 -> 4 -> 5is saved by thenextpointer. - Move pointers forward: Now, we have completed the reversal of node 1. Next, we need to process node 2. We move the
prevpointer to the position ofcurr(i.e., node 1), and move thecurrpointer to the position ofnext(i.e., node 2). Executeprev = curr(prev = 1), thencurr = next(curr = 2).
- Current state:
prev = 1,curr = 2,next = 2. - Current reversed part:
1 -> null - Remaining linked list:
2 -> 3 -> 4 -> 5 -> null
- Save the next node: First, we need a temporary pointer
-
Step Two: Process the second node (node 2)
- Save the next node:
next = curr.next(next = 3). - Reverse the pointer:
curr.next = prev. Make thenextof node 2 point to node 1. Now the linked list structure is2 -> 1 -> null. - Move pointers forward:
prev = curr(prev = 2),curr = next(curr = 3).
- Current state:
prev = 2,curr = 3,next = 3. - Current reversed part:
2 -> 1 -> null - Remaining linked list:
3 -> 4 -> 5 -> null
- Save the next node:
-
Step Three: Process the third node (node 3)
- Save the next node:
next = curr.next(next = 4). - Reverse the pointer:
curr.next = prev. Make thenextof node 3 point to node 2. Now the linked list structure is3 -> 2 -> 1 -> null. - Move pointers forward:
prev = curr(prev = 3),curr = next(curr = 4).
- Current state:
prev = 3,curr = 4,next = 4. - Current reversed part:
3 -> 2 -> 1 -> null - Remaining linked list:
4 -> 5 -> null
- Save the next node:
-
Steps Four and Five: And so on...
- We repeat this process until the last node (node 5) is processed.
-
Step Six: Process the last node (node 5) and termination condition
- At this point,
currpoints to node 5, andprevpoints to node 4. The linked list state is4 -> 3 -> 2 -> 1 -> null, remaining5 -> null. - Save the next node:
next = curr.next(next = null). - Reverse the pointer:
curr.next = prev. Make thenextof node 5 point to node 4. The linked list structure becomes5 -> 4 -> 3 -> 2 -> 1 -> null. - Move pointers forward:
prev = curr(prev = 5),curr = next(curr = null).
- Now, the
currpointer isnull, which means we have traversed all nodes of the original linked list.
- At this point,
-
Return Result
- After the loop ends, the
prevpointer points to the head node of the new reversed linked list, which is the tail node of the original list (node 5). Therefore, we finally returnprev.
- After the loop ends, the
Summary
The core of this iterative algorithm lies in performing the same four operations in each step:
- Temporarily save the next node of the current node (
next = curr.next). - Make the current node's pointer point to the previous node (reversal operation,
curr.next = prev). - Move the
prevpointer forward (prev = curr). - Move the
currpointer forward (curr = next).
The loop terminates when the curr pointer becomes null. The time complexity of the entire algorithm is O(n), where n is the length of the linked list, because we only traverse the list once. The space complexity is O(1), as we only use a few fixed pointers and no additional data structures.