Hey fellow devs! ๐
Today I was doing a revision of linkedList basics and encountered this leetcode problem. I actually forgot how to do it and had to solve it again and found the problem quite satisfying with a simple elegant solution. I thought I would share it here
The problem is Merge Two Sorted LinkedLists
You are given the heads of two sorted linked lists list1 and list2.
Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists.
Return the head of the merged linked list.
So I started thinking โ โHey, this is basically merging two sorted arrays, right?โ So I just tried to replicate that logic but with linked lists.
And boom ๐ฅ โ it worked.
Here's the version I first wrote:
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 is None: return l2
if l2 is None: return l1
i, j = l1, l2
head, k = None, None
while i and j:
if i.val <= j.val:
newNode = ListNode(i.val)
i = i.next
else:
newNode = ListNode(j.val)
j = j.next
if head is None:
head = newNode
k = head
else:
k.next = newNode
k = k.next
while i:
k.next = ListNode(i.val)
k = k.next
i = i.next
while j:
k.next = ListNode(j.val)
k = k.next
j = j.next
return head
This version creates a new list by copying values โ clean and readable. But then something hit me...
Wait โ in most linked list problems, they care about actual node identity too. What if they checked if I used the same node instances from the input lists?
So I sat with it for sometime then realised the issue is with head initialization. Then it hit me what if I just initialize a dummy head and just reference the original nodes instead of duplicating them. Then while returning just return the next node to the dummy next. That led to this version:
A cleaner, simpler approach:
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
if not list1:
return list2
if not list2:
return list1
i, j = list1, list2
head = ListNode(0)
res = head
while i and j:
if i.val <= j.val:
res.next = i
i = i.next
else:
res.next = j
j = j.next
res = res.next
res.next = i if i else j
return head.next
This version feels a lot more elegant โ fewer allocations, reuses existing nodes, and itโs just simpler to reason about. Just adding a dummy head node made the solution much easier and robust.
Sometimes, taking a step back and asking โhow can I improve this?โ leads to those little "aha!" moments that make problem-solving so satisfying. And next time I face a similar problem, Iโll definitely think of this approach โ not because I saw it in a video, but because I discovered it myself by playing around.
Have you had any moments like this โ where something just clicks while youโre coding or debugging? Would love to hear your stories!
Top comments (0)