Context: I am trying to simulate in vscode the leetcode's test case since leetcode doesn't offer debugger available for free users. https://leetcode.com/problems/merge-two-sorted-lists/
Here's the code solution from the discussions tab:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def add_nodes(self, parent, vals):
while len(vals) > 0:
node = ListNode(vals[0])
parent.next = node
return self.add_nodes(node, vals[1:])
class Solution:
def mergeTwoLists(self, list1: ListNode, list2: ListNode) -> ListNode:
l1 = []
while list1 != None:
l1.append(list1.val)
list1 = list1.next
while list2 != None:
l1.append(list2.val)
list2 = list2.next
l1.sort()
if l1 == []:
return None
new_list = ListNode(l1[0])
new_list.add_nodes(new_list, l1[1:])
return new_list
# The code below is what I used inside vscode to simulate leetcode's test case
program = Solution()
list = program.mergeTwoLists(ListNode([1, 3, 4]), ListNode([1, 2, 4]))
print(list.__dict__)
What I'm trying to accomplish: I want to print the returned object in the solution
class.
What I expected to happen: I'd expect that 2 linked lists [1,2,4] [1,3,4] are merged and the printed output would be [1,1,2,3,4,4]
Problem: However these is the only method I've scalped in my research and It still doesn't work print(list.__dict__)
. The printed output is
{'val': [1, 2, 4], 'next': <__main__.ListNode object at 0x0000024D48203460>}
CodePudding user response:
Although your merge code does not seems working (yet), you can use the following for debugging purpose:
def to_strs(node):
if not node: # None node
return []
return [str(node.val), *to_strs(node.next)]
print(' | '.join(to_strs(lst))) # [1, 2, 4] | [1, 3, 4]
CodePudding user response:
You can add a __repr__()
method to the ListNode class. This will allow you to simply print the result (which you shouldn't call list
because that's a Python type name):
def __repr__(self):
return f"{self.val}-->{self.next}" if self.next else f"{self.val}"
CodePudding user response:
Some issues:
Your main code passes a list to the
ListNode
constructor, but it will interpret that as a single value for one node. Instead you should call theadd_nodes
method.In fact, it makes more sense to have a class method (not an instance method) to create a new linked list from a standard list
To print the values in a linked list, I like to implement
__iter__
, which can be useful for many other purposes as well, and then base__str__
on that.
So your class could look like this:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
@classmethod
def fromvalues(Cls, values):
head = None
for value in reversed(values):
head = Cls(value, head)
return head
def __iter__(self):
yield self.val
if self.next:
yield from self.next
def __str__(self):
return "->".join(map(str, self))
And your main code like this:
program = Solution()
list = program.mergeTwoLists(ListNode.fromvalues([1, 3, 4]), ListNode.fromvalues([1, 2, 4]))
print(list)
Please be aware that there are more efficient ways to solve this code challenge:
It is not memory efficient to first store the result in a standard list and then convert that to a linked list. You should try to do this without that intermediate standard list and create the final linked list immediately from the input lists.
Your implementation does not use the given fact that the input linked lists are sorted. This means you should be able to do this without calling a
sort
method, and instead merge the lists by always picking the head node that has the least value when compared with other head nodes. Then remove that head node from the list it is in, and use it for building the result. You can even rewire the nodes in-place.