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.
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
// Initialize previous node to null
let prev = null;
// Initialize current node to head
let current = head;
// Iterate through the list
while (current !== null) {
// Store the next node
let next = current.next;
// Reverse the link
current.next = prev;
// Move prev and current one step forward
prev = current;
current = next;
}
// Return the new head of the reversed list
return prev;
};
### Explanation of Key Parts
- **Initialization**: `prev` is initialized to `null` because the new tail of the list will point to `null`.
- **Iteration**: The loop continues until `current` becomes `null`, indicating the end of the list.
- **Reversing the Link**: `current.next = prev` reverses the direction of the link.
- **Updating Pointers**: `prev` and `current` are moved one step forward to continue the process.
## Complexity Analysis
- **Time Complexity**: O(n), where n is the number of nodes in the list. Each node is visited exactly once.
- **Space Complexity**: O(1), as no additional space proportional to the input size is used.
## Edge Cases
- **Empty List**: If the list is empty (`head` is `null`), the function should return `null`.
- **Single Node**: If the list contains only one node, the function should return that node as it is.
### Example of Edge Cases
1. **Empty List**: `head = null`
**Output**: `null`
2. **Single Node**: `head = [1]`
**Output**: `[1]`
## Testing
To test the solution comprehensively, consider the following test cases:
1. A list with multiple nodes.
2. An empty list.
3. A list with a single node.
4. A list with duplicate values.
### Example Test Cases
// Test case 1: Multiple nodes
let head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
console.log(reverseList(head)); // Output: [5, 4, 3, 2, 1]
// Test case 2: Empty list
head = null;
console.log(reverseList(head)); // Output: null
// Test case 3: Single node
head = new ListNode(1);
console.log(reverseList(head)); // Output: [1]
// Test case 4: Duplicate values
head = new ListNode(1, new ListNode(1, new ListNode(1)));
console.log(reverseList(head)); // Output: [1, 1, 1]
## Thinking and Problem-Solving Tips
- **Understand the Problem**: Break down the problem into smaller parts and understand the requirements.
- **Visualize**: Draw diagrams to visualize the linked list and the reversal process.
- **Practice**: Solve similar problems to strengthen your understanding of linked lists and pointers.
## Conclusion
Reversing a linked list is a fundamental problem that helps in understanding pointers and linked list manipulations. By practicing such problems, you can improve your problem-solving skills and gain a deeper understanding of data structures.
## Additional Resources
- [LeetCode - Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/)
- [GeeksforGeeks - Reverse a Linked List](https://www.geeksforgeeks.org/reverse-a-linked-list/)
- [YouTube - Reverse Linked List Tutorial](https://www.youtube.com/watch?v=O0By4Zq0OFc)
By following this comprehensive guide, you should be able to understand and implement the solution to reverse a linked list efficiently. Happy coding!