I have edited the code to incorporate the notes from below (from Trincot), the only thing I am still not clear about is the “l1.next= MergeTwoLists(l1.next,l2)” ; I still don’t think this is right- any ideas how to amend this?
Also, do I need a while statement, since the recursive call seems to loop in some sense already.
Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
def MergeTwoLists(l1,l2):
prehead = ListNode(-1)
pointer_run = prehead
#Base Case
if not l1:
return l2
if not l2:
return l1
#Recurrence Relation
while l1 or l2:
if l1.val < l2.val:
pointer_run.next = l1
l1_temp = l1.val
l1.next= MergeTwoLists(l1.next,l2)
else:
pointer_run.next = l2
l2.next = MergeTwoLists(l1,l2.next)
return prehead.next
Advertisement
Answer
I am getting None as the output.
This happens when l2.val == l1.val. This is a case that is not captured by any if in your code, and so prehead.next is executed. But that next attribute never received a value other than the initial value, which I suppose is set to None by the ListNode constructor.
There are the following issues:
The last
ifshould really be anelse, as you want to capture the above described case in one of those two blocks. As both these blocks (theifblock and nowelseblock) end with areturn, there should be no possibility to ever get toreturn prehead.next: that statement can be removed. That also means thatpreheadis never read after itsnextattribute is assigned a value, and therefore serves no purpose.return MergeTwoLists(l1.next,l2)is not correct. You need to assign the returned value tol1.next. And to avoid that you mutate the input lists, you should first make a new node with the value atl1and assign to that new node’snextattribute. The same is true for the mirrored situation.The first base case is not necessary, as it is covered by the next.
As ListNode was not given, I add the definition that I will use in the corrected code:
class ListNode:
# Constructor allows caller to optionally provide a next node
def __init__(self, val, nxt=None):
self.val = val
self.next = nxt
# A method to ease the iteration of all list values
def values(self):
yield self.val
if self.next:
yield from self.next.values()
# Define the representation of a list (e.g. for printing)
def __repr__(self):
return " → ".join(map(repr, self.values()))
# A class method to ease the creation of a list
@classmethod
def fromvalues(cls, *values):
head = None
for val in reversed(values):
head = cls(val, head)
return head
Here is the corrected function:
def MergeTwoLists(l1, l2):
if not l1:
return l2
if not l2:
return l1
if l1.val < l2.val:
return ListNode(l1.val, MergeTwoLists(l1.next, l2))
else:
return ListNode(l2.val, MergeTwoLists(l1, l2.next))
Here is how you can run it:
l1 = ListNode.fromvalues(1, 2, 4) l2 = ListNode.fromvalues(1, 3, 4) result = MergeTwoLists(l1, l2) print(result) # 1 → 1 → 2 → 3 → 4 → 4