Today, I spent several hours debugging a Linked List problem, and by the end of it, I gained a much deeper understanding of references, pointers, and why some patterns exist in the first place.
π Current Problem: Merge Two Sorted Lists
Before starting this problem, I was feeling confident because I had already solved Add Two Numbers by directly modifying the original linked list instead of creating a completely new one.
My solution:
https://leetcode.com/problems/add-two-numbers/solutions/8345486/add-two-numbers-using-in-place-modificat-no1j
In that problem, I reused the existing nodes, updated values in-place, and only created new nodes when absolutely necessary.
List1.val = sum % 10;
If the list ended and there was still a carry:
prev.next = new ListNode(rem);
The approach worked beautifully.
The solution was accepted, and more importantly, I understood why it worked.
So when I started Merge Two Sorted Lists, my first thought was:
"Why create a dummy node? I already solved Add Two Numbers by modifying the original linked list. I should be able to do the same thing here."
That assumption sent me into one of the longest debugging sessions I've had recently.
My Initial Approach
Given:
list1 = 1 -> 2 -> 4
list2 = 1 -> 3 -> 4
Expected:
1 -> 1 -> 2 -> 3 -> 4 -> 4
My plan seemed straightforward:
- Traverse both lists.
- Compare values.
- Insert nodes where necessary.
- Modify
list1directly. - Return the modified list.
Simple.
At least that's what I thought.
Hours of Debugging Later...
I wrote the code.
Ran test cases.
Failed.
Added logs.
Failed again.
Added more logs.
Still failed.
Then I started manually dry-running every iteration.
I opened Excalidraw and literally drew:
- Every node
- Every pointer
- Every insertion
- Every reference update
And that's when I finally noticed what was actually happening.
The Mistake Wasn't In My Logic
The mistake was in my understanding.
While traversing the linked list, I kept moving my pointers:
head1 = head1.next;
head2 = head2.next;
I was using the same variable for two completely different responsibilities:
- Keeping track of the original head.
- Traversing the list.
Example:
head1
β
1 -> 2 -> 4
After:
head1 = head1.next;
head1
β
2 -> 4
Again:
head1 = head1.next;
head1
β
4
Again:
head1 = head1.next;
head1
β
null
At that moment, I realized something important:
I had completely lost the reference to the beginning of the list.
And once a reference is lost in a linked list, there's no way to magically get it back.
Why My Add Two Numbers Approach Worked
This was the breakthrough moment.
In Add Two Numbers, I wasn't changing the structure of the linked list.
I was only modifying values.
List1.val = sum % 10;
The nodes stayed connected.
The original head never changed.
The linked list structure remained intact.
So modifying the original list worked perfectly.
Why The Same Idea Fails Here
In Merge Two Sorted Lists, the situation is completely different.
We are not simply updating values.
We are:
- Connecting nodes from two different linked lists.
- Rearranging node relationships.
- Managing multiple references.
- Building an entirely new traversal path.
This means reference management becomes more important than the comparison logic itself.
A single lost reference can disconnect part of the list.
A single incorrect pointer update can break the entire structure.
That's exactly what I was running into during debugging.
The Moment Dummy Nodes Finally Made Sense
Earlier, I used to think:
"Dummy nodes are just an extra step."
Now I understand why they're one of the most common patterns in Linked List problems.
let dummy = new ListNode(-1);
let current = dummy;
The dummy node provides a permanent starting point.
No matter how many times I move pointers:
current = current.next;
I can always access the merged list through:
dummy.next;
Benefits:
β Never lose the head reference
β No special handling for the first node
β Cleaner insertion logic
β Easier debugging
β Cleaner interview solution
Biggest Lessons From Today
Technical Lessons
β Difference between modifying node values and modifying node connections
β Why preserving references is critical in Linked Lists
β Why Add Two Numbers and Merge Two Sorted Lists require different thinking
β How easily a head pointer can be lost
β Why Dummy Nodes are used so frequently
β The importance of visual dry runs
Non-Technical Lessons
Today reminded me that solving problems isn't always about writing more code.
Sometimes progress looks like:
- Writing code
- Failing
- Debugging
- Drawing diagrams
- Questioning assumptions
- Understanding why your approach doesn't work
The most valuable part of today's session wasn't finding the answer.
It was understanding why my original answer failed.
Tomorrow's Goal π―
Tomorrow I'll solve Merge Two Sorted Lists again, this time using the Dummy Node pattern and building the merged linked list step by step while preserving all references correctly.
I didn't get an accepted solution today.
But I gained something more valuable:
A much deeper understanding of how Linked Lists actually work under the hood.
And that's a win I'll happily take.
Top comments (0)