Given the head of a singly linked list, reverse the list, and return the reversed list.
Example:
Input: head =[1, 2, 3, 4, 5]Output:[5, 4, 3, 2, 1]
Your algorithm should run in O(n) time and use O(1) extra space.
The task is to reverse a singly linked list. Given the head of the list, we need to reverse the list and return the new head.
A singly linked list represented by its head node.
The head of the reversed linked list.
Input: head = [1, 2, 3, 4, 5] Output: [5, 4, 3, 2, 1]
The core challenge is to reverse the links between nodes in a singly linked list. This problem is significant in many applications, such as reversing data streams or undoing operations. A common pitfall is losing access to the next node when reversing the link, which can be avoided by careful pointer manipulation.
To solve this problem, we need to reverse the direction of the links between nodes. We can achieve this by iterating through the list and adjusting the pointers.
A naive approach might involve using additional space to store the nodes in a different order, but this would not meet the O(1) space requirement.
We can use an iterative approach with three pointers: prev, current, and next. This method ensures we reverse the list in O(n) time and O(1) space.
prev to null, current to head, and next to null.next pointer of the current node to point to prev.prev and current pointers one step forward.prev as the new head of the reversed list.Here is a step-by-step breakdown of the algorithm:
prev to null and current to head.current is not null:
current->next in next.current->next to prev.prev to current.current to next.prev as the new head.// 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; // Initialize previous node to null
ListNode* current = head; // Start with the head node
ListNode* next = nullptr; // Initialize next node to null
while (current != nullptr) { // Traverse the list
next = current->next; // Store the next node
current->next = prev; // Reverse the current node's pointer
prev = current; // Move prev to current node
current = next; // Move to the next node
}
return prev; // prev will be the new head of the reversed list
}
};
The time complexity of this approach is O(n) because we traverse the list once. The space complexity is O(1) as we only use a constant amount of extra space for the pointers.
Consider the following edge cases:
To test the solution comprehensively, consider the following test cases:
1. Input: head = [] Output: [] 2. Input: head = [1] Output: [1] 3. Input: head = [1, 2, 3, 4, 5] Output: [5, 4, 3, 2, 1] 4. Input: head = [1, 2] Output: [2, 1]
When approaching such problems, consider the following tips:
Reversing a linked list is a fundamental problem that helps in understanding pointer manipulation and linked list operations. Mastering this problem enhances your problem-solving skills and prepares you for more complex data structure challenges.
For further reading and practice, consider the following resources:
Our interactive tutorials and AI-assisted learning will help you master problem-solving skills and teach you the algorithms to know for coding interviews.
Start Coding for FREE