I was doing the following LeetCode exercise
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 and l2:
if l1.val < l2.val:
temp = head = ListNode(l1.val)
l1 = l1.next
else:
temp = head = ListNode(l2.val)
l2 = l2.next
while l1 and l2:
if l1.val < l2.val:
temp = temp.next = ListNode(l1.val)
#temp.next = temp = ListNode(l1.val)
l1 = l1.next
else:
temp = temp.next = ListNode(l2.val)
#temp.next = temp = ListNode(l2.val)
l2 = l2.next
...
My question is why the lines temp = temp.next = ListNode(l1.val) and temp = temp.next = ListNode(l2.val) don't work and the commented lines right below them do?
They mean fundamentally different things:
temp = temp.next = ListNode(l1.val)
is equivalent to:
_node = ListNode(l1.val)
temp = _node
temp.next = _node
Whereas
temp.next = temp = ListNode(l1.val)
is equivalent to:
_node = ListNode(l1.val)
temp.next = _node
temp = _node
The second one assigns the next property of the current temp node to a new node, then sets temp to be the new node, which is the correct behavior. The first sets temp to the new node, then sets its next property to be itself, which is incorrect.
Related
I implemented a linked list. And now I should sum each corresponding item of the two Linked Lists.
This is the implementation of the Linked list
class Node:
def __init__(self, data=0, next_node=None):
self.data = data
self.next_node = next_node
class LinkedList:
def __init__(self):
self.head = None
def __iter__(self):
current = self.head
while current is not None:
yield current.data
current = current.next_node
def add_last(self, node):
if self.head is None:
self.head = node
return
current = self.head
while current.next_node:
current = current.next_node
current.next_node = node
But when I sum items of each linked list, I am having an infinite loop and my linked list is not iterating
Here is the summing process
def two_sum(list1: LinkedList, list2: LinkedList) -> LinkedList:
l1 = list1.head
l2 = list2.head
res_list = LinkedList()
carry = 0
while l1 is not None or l2 is not None:
x = l1.data if l1 else 0
y = l2.data if l2 else 0
sum = carry + x + y
res_list.add_last(Node(sum % 10))
carry = carry // 10
l1 = l1.next_node if l1.next_node else l1
l2 = l2.next_node if l2.next_node else l2
if carry > 0:
res_list.add_last(Node(carry))
return res_list
Observe that:
l1 = l1.next_node if l1.next_node else l1
l2 = l2.next_node if l2.next_node else l2
Is wrong.
That condition:
if l1.next_node
Won't assign None to l1/l2
You can drop the if l1.next_node else l1
class Node:
def __init__(self, data):
self.key = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
L1 = LinkedList()
print(L1.head)
def Insert(key,root):
temp = root
if (root != None):
while(temp.next):
temp = temp.next
temp.next = Node(key)
print("donr next")
else:
root = Node(key)
print("doneroot")
list1 = [1,2,3,4,5,6]
for i in range(0,len(list1)):
Insert(list1[i],L1.head)
def printing(ll):
temp = ll.head
print("printing")
print(temp)
while(temp):
print(temp.key)
temp = temp.next
printing(L1)
The ouput is:
None
doneroot
doneroot
doneroot
doneroot
doneroot
printing
None
Why it is always adding to the root element
In Python, everything is passed by reference. When the passed object is immutable, the label actually gets reassigned in its scope. For example:
def modify_a_list(x): # lists are mutable
x.append(1)
def modify_a_string(x): # strings are immutable
x += 'bar'
a = [3,2]
modify_a_list(a)
print(a) # gives [3, 2, 1]
b = 'text'
modify_a_string(b)
print(b) # prints 'text' and not 'textbar'.
In your example, when you pass L1.head as a parameter, it resolves to None and the newly defined label | variable named root inside you method reassigns to a new Node. But you wanted to assign it to attribute head of the linked list. This can be solved by passing the linked list as the parameter.
class Node:
def __init__(self, data):
self.key = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
L1 = LinkedList()
print(L1.head)
def Insert(key, ll):
temp = ll.head
if ll.head is not None:
while temp.next:
temp = temp.next
temp.next = Node(key)
print("donr next")
else:
ll.head = Node(key)
print("doneroot")
list1 = [1,2,3,4,5,6]
for i in range(0,len(list1)):
Insert(list1[i], L1)
def printing(ll):
temp = ll.head
print("printing")
print(temp)
while temp:
print(temp.key)
temp = temp.next
printing(L1)
Below is the answer to the addTwoNumbers linked node list question on LeetCode.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
result = ListNode(0)
temp = result
carry = 0
while l1 or l2 or carry:
val1 = (l1.val if l1 else 0)
val2 = (l2.val if l2 else 0)
carry, out = divmod(val1+val2 + carry, 10)
temp.next = ListNode(out)
temp = temp.next
l1 = (l1.next if l1 else None)
l2 = (l2.next if l2 else None)
return result.next
I am struggling to understand how
result = ListNode(0)
temp = result
outside the while loop and
temp.next = ListNode(out)
temp = temp.next
inside the while loop stores the linked nodes.
I feel that the code should leave result.next unchanged, as result is never called in the while loop, but it clearly isn't the case.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, self.next)
class Solution(object):
def mergeTwoLists(self, l1, l2):
curr = dummy = ListNode(0)
while l1 and l2:
if l1.val < l2.val:
curr.next = l1
l1 = l1.next
else:
curr.next = l2
l2 = l2.next
curr = curr.next
curr.next = l1 or l2
return dummy.next
ln1 = ListNode(1)
ln2 = ListNode(2)
ln3 = ListNode(4)
ln4 = ListNode(1)
ln5 = ListNode(3)
ln6 = ListNode(4)
ln1.next = ln2
ln2.next = ln3
ln4.next = ln5
ln5.next = ln6
s = Solution()
result = s.mergeTwoLists(ln1, ln4)
print(result)
A python code to solve a leetcode problem #21. The question is when the code runs at curr.next = l1 or curr.next = l2, the curr changes and the dummy also changes. However, when runs at curr = curr.next, only curr runs but dummy doesn't change. Why it happens like this?
The similar situation in Python is:
a = b = [1, 2, 3]
b = [1, 2, 3, 4]
print(a)
a = b = [1, 2, 3]
b.append(4)
print(a)
the first a doesn't change but the second a changes
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
def printListNode(y):
print "start"
while y:
print y.val
y = y.next
print "end"
temp = ListNode(0)
result = temp
while l1 and l2:
if l1.val < l2.val:
result.next = l1
l1 = l1.next
else:
result.next = l2
l2 = l2.next
result = result.next
printListNode(temp)
printListNode(result)
if l1:
result.next = l1
if l2:
result.next = l2
return temp.next
if __name__ == "__main__":
solution = Solution()
test1 = ListNode(2)
test1.next = ListNode(3)
test2 = ListNode(1)
test2.next = ListNode(4)
print(solution.mergeTwoLists(test1, test2))
As you can see I have printListNode(temp) and printListNode(result). What confused me is they print different result... for temp: it print 0,1,2,3 But for result: just 3. Why? I think result = temp means result equals to temp...
You have updated result with different value inside loop
result = temp # <- assigning value of temp to result
while l1 and l2:
if l1.val < l2.val:
result.next = l1
l1 = l1.next
else:
result.next = l2
l2 = l2.next
result = result.next # <- assigning rsult.next to result
printListNode(temp)
printListNode(result)
You assigned temp to ListNode(0) after this assignment and this remained unchanged when u called the printListNode function
temp = ListNode(0);
Then u assigned result to be same as temp, only at this moment they are the same.
result = temp;
However inside the loop, u modified the content of result under these possible executions
result.next = l1;
result.next = l2;
result = result.next;
temp is still unchanged . Hence they will have different result.