Problem Statement
Given the head of a singly linked list, reverse the list and return its head.
Function Signature:
go
func reverseList(head *ListNode) *ListNode
Example 1:
go
head := &ListNode{Val: 1}
head.Next = &ListNode{Val: 2}
head.Next.Next = &ListNode{Val: 3}
head.Next.Next.Next = &ListNode{Val: 4}
head.Next.Next.Next.Next = &ListNode{Val: 5}
fmt.Println(reverseList(head))
// Output: [5, 4, 3, 2, 1]
Explanation: The linked list is reversed, so the order is [5, 4, 3, 2, 1]
.
Example 2:
go
fmt.Println(reverseList(nil))
// Output: nil
Explanation: An empty list is reversed and remains empty.
Constraints:
- The number of nodes in the list is in the range
[0, 5000]
.
-5000 <= Node.val <= 5000
.
Approach
To reverse a singly linked list, we need to iteratively traverse the list and reverse the direction of the pointers. This can be done using three pointers:
- Previous Pointer: This will point to the previous node in the list.
- Current Pointer: This will point to the current node being processed.
- Next Pointer: This will point to the next node to prevent losing the rest of the list.
Steps:
- Start by setting the
previous
pointer to nil
and the current
pointer to the head of the list.
- Traverse the list while the
current
pointer is not nil
:
- Store the next node (
next
).
- Reverse the link by pointing
current.Next
to previous
.
- Move the
previous
pointer to current
, and the current
pointer to next
.
- Once the traversal is complete, the
previous
pointer will point to the new head of the reversed list.
Time Complexity:
- O(n), where
n
is the number of nodes in the linked list. We visit each node once.
Space Complexity:
- O(1), since we are only using a constant amount of space (3 pointers) regardless of the size of the input list.
Go Implementation
go
package main
import "fmt"
// ListNode is the structure of a node in the singly linked list
type ListNode struct {
Val int
Next *ListNode
}
// Function to reverse the linked list
func reverseList(head *ListNode) *ListNode {
var previous *ListNode = nil
current := head
// Traverse the list and reverse the links
for current != nil {
next := current.Next // Store the next node
current.Next = previous // Reverse the current node's pointer
previous = current // Move previous to the current node
current = next // Move to the next node
}
return previous // At the end, previous will be the new head of the reversed list
}
// Helper function to print the linked list
func printList(head *ListNode) {
for head != nil {
fmt.Print(head.Val, " ")
head = head.Next
}
fmt.Println()
}
func main() {
// Example 1: Create a linked list [1, 2, 3, 4, 5]
head := &ListNode{Val: 1}
head.Next = &ListNode{Val: 2}
head.Next.Next = &ListNode{Val: 3}
head.Next.Next.Next = &ListNode{Val: 4}
head.Next.Next.Next.Next = &ListNode{Val: 5}
fmt.Println("Original List:")
printList(head)
// Reverse the linked list
reversedHead := reverseList(head)
fmt.Println("Reversed List:")
printList(reversedHead)
// Example 2: Reverse an empty linked list
fmt.Println("Reversed Empty List:")
printList(reverseList(nil)) // Output: nil
}
Explanation of the Code:
1. ListNode Structure:
- We define a
ListNode
struct which represents a node in a singly linked list. Each node contains a value (Val
) and a pointer to the next node (Next
).
2. reverseList Function:
- Input: The function takes the
head
of the linked list as an argument.
- Initialization: We initialize two pointers:
previous
is set to nil
(this will be the new tail of the list).
current
is set to head
(this will traverse through the list).
- Traversal & Reversal: We iterate through the list:
- For each node, we store the
next
node to avoid losing reference to the rest of the list.
- We then reverse the link by setting
current.Next
to previous
.
- Move
previous
to current
and current
to next
.
- Return: Once the traversal is complete,
previous
will be the new head of the reversed list, which we return.
3. Helper Function printList:
- This function is used to print the values of the linked list nodes in order, so we can visualize the list before and after reversal.
4. Main Function:
- The
main
function demonstrates how to create a linked list, reverse it, and print the results.
Example Walkthrough
Example 1:
Input:
go
head := &ListNode{Val: 1}
head.Next = &ListNode{Val: 2}
head.Next.Next = &ListNode{Val: 3}
head.Next.Next.Next = &ListNode{Val: 4}
head.Next.Next.Next.Next = &ListNode{Val: 5}
The linked list is:
rust
1 -> 2 -> 3 -> 4 -> 5
- Step 1: The
current
pointer starts at 1
, and the previous
pointer is nil
.
- Step 2: The
next
pointer stores the next node (2
). We reverse the link so that 1
now points to nil
.
- Step 3: Move
previous
to 1
and current
to 2
. Repeat the process until the current
pointer reaches nil
.
- Step 4: The reversed list is:
rust
5 -> 4 -> 3 -> 2 -> 1
Output:
yaml
Reversed List: 5 4 3 2 1
Example 2:
Input:
go
printList(reverseList(nil))
For an empty list (nil
), the function returns nil
, and the output is:
mathematica
Reversed Empty List:
Conclusion
The LeetCode 206: Reverse Linked List problem is a fundamental problem that can be solved efficiently using an iterative approach with three pointers. The space complexity is O(1), and the time complexity is O(n), where n
is the number of nodes in the list. This is an optimal solution for this problem.