name: LinkedList In-Place Reversal slug: linkedlist-reversal difficulty_level: 2 pattern_type: technique display_order: 14 description: > Reverse linked list nodes in-place by manipulating pointers without allocating extra space. This technique uses three pointers to track the previous, current, and next nodes while systematically reversing the direction of links. when_to_use: | - Reversing an entire linked list - Reversing a portion of a linked list - Reversing in groups of K nodes - Palindrome linked list verification - Reordering list problems metaphor: | Imagine a conga line where everyone faces forward. To reverse it, you don't rearrange people—you have each person turn around and grab the shoulders of whoever was behind them. You process one person at a time: they turn around, the next person steps forward, and so on until everyone faces the opposite direction. Another analogy: reversing a chain of paper clips. You unclip each one from its forward neighbor and clip it to its backward neighbor, working through the chain. core_concept: | Linked list reversal uses **three pointers** moving through the list: - **prev**: Points to the already-reversed portion (starts as null) - **curr**: The node currently being processed - **next**: Temporarily stores the next node before we break the link At each step: 1. Save `curr.next` in `next` (before we lose it) 2. Reverse the link: `curr.next = prev` 3. Advance: `prev = curr`, `curr = next` The key insight is that we're not moving nodes—we're redirecting pointers. This achieves O(n) time with O(1) space. For **partial reversal** (reversing between positions m and n), we: 1. Navigate to position m-1 (the node before reversal starts) 2. Reverse nodes from m to n 3. Reconnect the reversed portion to the rest of the list visualization: | **Full list reversal:** ``` Initial: 1 → 2 → 3 → 4 → null prev=null, curr=1 Step 1: Save next=2, reverse 1's link null ← 1 2 → 3 → 4 prev curr Step 2: Save next=3, reverse 2's link null ← 1 ← 2 3 → 4 prev curr Step 3: Save next=4, reverse 3's link null ← 1 ← 2 ← 3 4 prev curr Step 4: Save next=null, reverse 4's link null ← 1 ← 2 ← 3 ← 4 prev curr=null Result: 4 → 3 → 2 → 1 → null ``` **Partial reversal (positions 2 to 4):** ``` Initial: 1 → 2 → 3 → 4 → 5 positions: 1 2 3 4 5 Goal: 1 → 4 → 3 → 2 → 5 Step 1: Find node before position 2 before = node 1 Step 2: Reverse nodes 2, 3, 4 1 null ← 2 ← 3 ← 4 5 ↑ ↑ ↑ before prev curr Step 3: Reconnect before.next.next = curr (2 → 5) before.next = prev (1 → 4) Result: 1 → 4 → 3 → 2 → 5 ``` code_template: | class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def reverse_list(head: ListNode) -> ListNode: """Reverse entire linked list.""" prev = None curr = head while curr: next_node = curr.next # Save next curr.next = prev # Reverse link prev = curr # Advance prev curr = next_node # Advance curr return prev # New head def reverse_between(head: ListNode, m: int, n: int) -> ListNode: """Reverse nodes from position m to n (1-indexed).""" if not head or m == n: return head dummy = ListNode(0) dummy.next = head before = dummy # Move to node before reversal starts for _ in range(m - 1): before = before.next # Reverse n - m + 1 nodes prev = None curr = before.next for _ in range(n - m + 1): next_node = curr.next curr.next = prev prev = curr curr = next_node # Reconnect before.next.next = curr # tail of reversed → rest of list before.next = prev # before → new head of reversed return dummy.next def reverse_k_group(head: ListNode, k: int) -> ListNode: """Reverse nodes in groups of k.""" # Count total nodes count = 0 node = head while node: count += 1 node = node.next dummy = ListNode(0) dummy.next = head before = dummy while count >= k: # Reverse k nodes prev = None curr = before.next for _ in range(k): next_node = curr.next curr.next = prev prev = curr curr = next_node # Reconnect tail = before.next tail.next = curr before.next = prev # Move to next group before = tail count -= k return dummy.next def reverse_list_recursive(head: ListNode) -> ListNode: """Reverse list using recursion.""" if not head or not head.next: return head new_head = reverse_list_recursive(head.next) head.next.next = head # Reverse link head.next = None # Prevent cycle return new_head recognition_signals: - "reverse linked list" - "reverse between" - "reverse in groups" - "reverse k-group" - "palindrome linked list" - "reorder list" - "swap nodes" - "rotate list" common_mistakes: - title: Losing reference to next node description: | Reversing `curr.next` before saving it means you can't advance to the next node. fix: | Always save the next node first: ```python next_node = curr.next # Save FIRST curr.next = prev # Then reverse ``` - title: Forgetting to update connections in partial reversal description: | Reversing the middle portion without reconnecting it to the beginning and end of the list breaks the list. fix: | After reversing, reconnect both ends: ```python before.next.next = curr # tail → rest before.next = prev # before → new head ``` - title: Not using a dummy node description: | When the reversal might include the head, handling the head separately adds complexity and edge cases. fix: | Use a dummy node pointing to head. This simplifies edge cases: ```python dummy = ListNode(0) dummy.next = head # ... reversal logic ... return dummy.next ``` - title: Off-by-one with positions description: | Confusing 0-indexed vs 1-indexed positions causes reversal of wrong nodes. fix: | Clarify indexing convention. For 1-indexed positions, loop `m-1` times to reach the node *before* position m. variations: - name: Full reversal description: | Reverse the entire linked list. Simplest form—just walk through and reverse each link. example: "Reverse Linked List" - name: Partial reversal description: | Reverse only nodes between positions m and n. Need to track connection points before and after the reversed section. example: "Reverse Linked List II" - name: K-group reversal description: | Reverse every k consecutive nodes. Often requires counting total nodes first to know when to stop. example: "Reverse Nodes in k-Group" - name: Alternating reversal description: | Reverse every other group of k nodes. Combines k-group logic with skip logic. example: "Reverse Alternate K Nodes" - name: Recursive reversal description: | Elegant recursive solution that reverses by relying on the recursive call to reverse the rest, then fixing up the current node. example: "Reverse Linked List (recursive approach)" related_patterns: - fast-slow-pointers - two-pointers prerequisite_patterns: [] visualization_examples: - id: reverse-linked-list title: Reverse Entire Linked List input: list: [1, 2, 3, 4] code: | def reverse_list(head): prev = None curr = head while curr: next_node = curr.next curr.next = prev prev = curr curr = next_node return prev steps: - id: step-1 description: "Initialize prev=None, curr=head (node 1)." structures: list: type: linkedlist nodes: - { value: 1, state: active } - { value: 2, state: default } - { value: 3, state: default } - { value: 4, state: default } pointers: curr: 0 variables: prev: "null" codeHighlight: startLine: 2 endLine: 3 - id: step-2 description: "Save next=2, reverse link: 1→null. Move pointers forward." structures: list: type: linkedlist nodes: - { value: 1, state: visited, annotations: ["→null"] } - { value: 2, state: active } - { value: 3, state: default } - { value: 4, state: default } pointers: prev: 0 curr: 1 variables: next_node: 2 codeHighlight: startLine: 6 endLine: 9 - id: step-3 description: "Save next=3, reverse link: 2→1. Move pointers forward." structures: list: type: linkedlist nodes: - { value: 1, state: visited, annotations: ["→null"] } - { value: 2, state: visited, annotations: ["→1"] } - { value: 3, state: active } - { value: 4, state: default } pointers: prev: 1 curr: 2 variables: next_node: 3 codeHighlight: startLine: 6 endLine: 9 - id: step-4 description: "Save next=4, reverse link: 3→2. Move pointers forward." structures: list: type: linkedlist nodes: - { value: 1, state: visited, annotations: ["→null"] } - { value: 2, state: visited, annotations: ["→1"] } - { value: 3, state: visited, annotations: ["→2"] } - { value: 4, state: active } pointers: prev: 2 curr: 3 variables: next_node: 4 codeHighlight: startLine: 6 endLine: 9 - id: step-5 description: "Save next=null, reverse link: 4→3. curr becomes null, loop ends." structures: list: type: linkedlist nodes: - { value: 1, state: visited, annotations: ["→null"] } - { value: 2, state: visited, annotations: ["→1"] } - { value: 3, state: visited, annotations: ["→2"] } - { value: 4, state: found, annotations: ["→3", "new head"] } pointers: prev: 3 variables: next_node: "null" codeHighlight: startLine: 11 endLine: 11 - id: step-6 description: "Return prev (node 4). Reversed list: 4→3→2→1→null" structures: reversed: type: linkedlist nodes: - { value: 4, state: found, annotations: ["head"] } - { value: 3, state: default } - { value: 2, state: default } - { value: 1, state: default } variables: result: "4→3→2→1→null" codeHighlight: startLine: 11 endLine: 11