I am struggling with these linked list problems on leetcode (and the tree problems since they use a similar structure). Example https://leetcode.com/problems/merge-two-sorted-lists/
If I try to run this code outside of leetcode's magic box, I run into issues.
My mergeTwoLists function works great inside of the leetcode editor (runs successfully, is accepted)
from typing import Optional
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
prehead = ListNode(-1)
prev = prehead
while list1 and list2:
if list1.val <= list2.val:
prev.next = list1
list1 = list1.next
else:
prev.next = list2
list2 = list2.next
prev = prev.next
breakpoint()
prev.next = list1 if list1 is not None else list2
return prehead.next
if __name__ == '__main__':
l1 = ListNode(1)
l1_2 = ListNode(2)
l1_3 = ListNode(4)
l1.next = l1_2
l1_2.next = l1_3
l2 = ListNode(1)
l2_2 = ListNode(3)
l2_3 = ListNode(4)
l2.next = l1_2
l2_2.next = l1_3
print(mergeTwoLists(l1, l2))
The problem is that when I try to run the above standalone from my terminal it gets into an infinite loop.
The reason is that due to what I have passed into the function, if I throw a breakpoint() into the end of the first loop and inspect list1 and list2
(Pdb) list1
<__main__.ListNode object at 0x00000294E1F8FEE0>
(Pdb) list2
<__main__.ListNode object at 0x00000294E1F8FE20>
Which makes sense. It explains the infinite loop, class objects eval to True when cast to bool.
So based on this, if I want to get this code to run outside leetcode I need to do something differently. I need more info for my class definition, or my test case setup is wrong?
Does anyone know more about the complete definition of the ListNode class in Leetcode's system? Or is there something I am missing in how I should be setting up my test?
Thank you!
CodePudding user response:
So yes, you are correct, on your while list1 and list2
this evaluates to True
.
You can solve it like this, being more explicit:
def mergeTwoLists(list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
prehead = ListNode(-1)
prev = prehead
while (list1.next is not None) and (list2.next is not None):
if list1.val <= list2.val:
prev.next = list1
list1 = list1.next
else:
prev.next = list2
list2 = list2.next
prev = prev.next
prev.next = list1 if list1 is not None else list2
return prehead.next
It probably works in leetcode because they defined another method to the class. If you define the class like this:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def __bool__(self):
"""Return bool(self)."""
return self.next is not None
Then the __bool__
method will be called when you try to do list1 and list2
, and it does the same behavior.