Back to Linked List
Reverse Linked List
Reverse Linked List
š§© Problem Statement
Given the head of a singly linked list, reverse the list, and return the reversed list.
š¹ Example 1:
Input:
head = [1,2,3,4,5]
Output:
[5,4,3,2,1]
š¹ Example 2:
Input:
head = [1,2]
Output:
[2,1]
š¹ Example 3:
Input:
head = []
Output:
[]
š Approaches
1. Iterative
We iterate through the list and change the next pointer of each node to point to the previous node.
⨠Intuition
- Use three pointers:
prev,curr,nextTemp. prevtracks the confirmed reversed part (initially NULL).curris the node we are currently reversing.nextTempsaves the rest of the list so we don't lose it when we overwritecurr.next.
š„ Algorithm Steps
- Initialize
prev = NULL,curr = head. - While
curris not NULL:
- Save
nextTemp = curr.next. - Reverse:
curr.next = prev. - Advance:
prev = curr,curr = nextTemp.
- Return
prev(new head).
2. Recursive
We reverse the rest of the list first, then put the current node at the end of that reversed list.
ā³ Time & Space Complexity
- Time Complexity: $O(n)$, visit each node once.
- Space Complexity: $O(1)$ for iterative, $O(n)$ for recursive (stack depth).
š Code Implementations
C++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
};
Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
curr = head
while curr:
tmp = curr.next
curr.next = prev
prev = curr
curr = tmp
return prev
Java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
}
š Real-World Analogy
Turning a Train Around:
Imagine a train where each car points to the next.
- To reverse it car by car:
- You uncouple the first car (engine) from the second.
- You make the first car point to "nothing" (new end).
- You take the second car, uncouple it from the third, and couple it to the first.
- Repeat until the last car (caboose) becomes the new engine.
šÆ Summary
ā
O(1) Space: Iterative is most efficient.
ā
Foundation: critical for many linked list problems.
Solution Code
O(n) TimeO(1) Space
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
ListNode *reverseList(ListNode *head) {
ListNode *prev = nullptr;
ListNode *curr = head;
while (curr) {
ListNode *nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
};
void printList(ListNode *head) {
while (head) {
cout << head->val << (head->next ? "->" : "");
head = head->next;
}
cout << endl;
}
int main() {
Solution sol;
ListNode *head = new ListNode(
1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
cout << "Original: ";
printList(head);
head = sol.reverseList(head);
cout << "Reversed: ";
printList(head);
return 0;
}
SYSTEM STABLEUTF-8 ⢠STATIC_RENDER