Given the beginning of a singly linked list head, reverse the list, and return the new beginning of the list.
Example 1:
Input: head = [0,1,2,3]
Output: [3,2,1,0]Example 2:
Input: head = []
Output: []Constraints:
0 <= The length of the list <= 1000.-1000 <= Node.val <= 1000
You should aim for a solution with O(n) time and O(1) space, where n is the length of the given list.
A brute force solution would be to store the node values of the linked list into an array, then reverse the array, convert it back into a linked list, and return the new linked list's head. This would be an O(n) time solution but uses extra space. Can you think of a better way? Maybe there is an approach to reverse a linked list in place.
As you can see, the head of the linked list becomes the tail after we reverse it. Can you think of an approach to change the references of the node pointers? Perhaps reversing a simple two-node list might help clarify the process.
For example, consider a list [2, 3], where 2 is the head of the list and 3 is the tail. When we reverse it, 3 becomes the new head, and its next pointer will point to 2. Then, 2's next pointer will point to null. Can you figure out how to apply this approach to reverse a linked list of length n by iterating through it?
We can reverse the linked list in place by reversing the pointers between two nodes while keeping track of the next node's address. Before changing the next pointer of the current node, we must store the next node to ensure we don't lose the rest of the list during the reversal. This way, we can safely update the links between the previous and current nodes.
Reversing a linked list using recursion works by thinking in terms of “reverse the rest, then fix the pointer for the current node.”
When we recursively go to the end of the list, that last node becomes the new head.
While the recursion unwinds, each node points backward to the one that called it.
Finally, we set the original head’s next to None to finish the reversal.
This approach uses the call stack to naturally reverse the direction of the pointers.
None.head.next to reverse the rest of the list.head.next.next = head so the next node points back to the current node.head.next = None to avoid cycles.# 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]:
if not head:
return None
newHead = head
if head.next:
newHead = self.reverseList(head.next)
head.next.next = head
head.next = None
return newHeadReversing a linked list iteratively is all about flipping pointers one step at a time.
We walk through the list from left to right, and for each node, we redirect its next pointer to point to the node behind it.
To avoid losing track of the rest of the list, we keep three pointers:
curr → the current node we are processing prev → the node that should come after curr once reversed temp → the original next node (so we don’t break the chain)By moving these pointers forward in each step, we gradually reverse the entire list.
When curr becomes None, the list is fully reversed, and prev points to the new head.
prev = Nonecurr = headcurr exists:temp = curr.nextcurr.next = prevprev to currcurr to tempprev is the new head of the reversed list.prev.# 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: ListNode) -> ListNode:
prev, curr = None, head
while curr:
temp = curr.next
curr.next = prev
prev = curr
curr = temp
return prev