AW Dev Rethought

Programs must be written for people to read, and only incidentally for machines to execute - Harold Abelson

🧩 Python DSA Patterns — Linked List Patterns 🔗🐍


Description:

Linked list problems aren’t about indexes — they’re about pointer movement.

Once you learn a few core techniques (fast/slow pointers, dummy nodes, in-place reversal), most linked list questions follow predictable patterns.

This post focuses on the most reusable linked list patterns you’ll see again and again.


🧠 Core Linked List Patterns

  • In-place reversal (no extra memory)
  • Fast & slow pointers (cycle, middle)
  • Dummy nodes (safe deletions & merges)
  • Two-pointer traversal (from both ends conceptually)

📝 Reverse a Linked List (In-Place)

Reverse links one by one using three pointers.

def reverse_list(head):
    prev = None
    curr = head

    while curr:
        nxt = curr.next
        curr.next = prev
        prev = curr
        curr = nxt

    return prev

💡 Why it matters:

This pattern is reused in palindrome checks, k-group reversal, and list reordering.


📝 Detect Cycle (Fast & Slow Pointers)

If fast and slow pointers meet, a cycle exists.

def has_cycle(head):
    slow = fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True

    return False

💡 Insight:

Fast pointer laps the slow pointer inside a loop.


📝 Find the Middle of a Linked List

Fast pointer moves twice as fast as slow.

def middle_node(head):
    slow = fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

    return slow

💡 Common use:

Split lists, binary tree conversion, palindrome checks.


📝 Remove Nth Node From End (Dummy Node Trick)

A dummy node avoids edge cases when removing the head.

def remove_nth_from_end(head, n):
    dummy = ListNode(0, head)
    slow = fast = dummy

    for _ in range(n + 1):
        fast = fast.next

    while fast:
        slow = slow.next
        fast = fast.next

    slow.next = slow.next.next
    return dummy.next

💡 Why dummy helps:

It guarantees a safe previous node for deletion.


📝 Merge Two Sorted Linked Lists

Merge without creating new nodes.

def merge_two_lists(l1, l2):
    dummy = ListNode()
    tail = dummy

    while l1 and l2:
        if l1.val < l2.val:
            tail.next = l1
            l1 = l1.next
        else:
            tail.next = l2
            l2 = l2.next
        tail = tail.next

    tail.next = l1 or l2
        return dummy.next

💡 Pattern:

Build result using pointer rewiring, not extra memory.


🧠 Where Linked List Patterns Are Used

  • 🔁 Reversal & reordering problems
  • 🔄 Cycle detection
  • 🧩 Palindrome linked lists
  • 🔗 Merge & split operations
  • 🧠 Pointer-based optimizations

✅ Takeaway

  • Linked list solutions rely on pointer control
  • Fast/slow pointers solve cycle & middle problems
  • Dummy nodes simplify deletion logic
  • Most problems run in O(n) time, O(1) space

Once these patterns click, linked list problems become mechanical.


🏋️ Practice Problems

  1. Reverse Linked List
  2. Linked List Cycle
  3. Middle of the Linked List
  4. Remove Nth Node From End
  5. Merge Two Sorted Lists


📂 Full Script

The blog covers the essentials — find the complete notebook with all snippets & extras on GitHub Repo 👉 Python DSA Patterns


Link copied!

Comments

Add Your Comment

Comment Added!