Why these two print different output related with python =(assign) symbol - python

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.

Related

leetcode: add-two-numbers using linked list

I am trying to solve one of the medium level problems involving linked list which goes something like this
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
python code:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
l1_number = 0
i = 0
while l1:
l1_number+=l1.val*(10**i)
l1 = l1.next
i+=1
l2_number = 0
j = 0
while l2:
l2_number+=l2.val*(10**j)
l2 = l2.next
j+=1
sum_of_numbers = l2_number+l1_number
new_node=ListNode()
while sum_of_numbers > 0:
number = sum_of_numbers%10
while new_node.next:
new_node = new_node.next
new_node.next = ListNode(number)
sum_of_numbers=sum_of_numbers//10
return new_node
I am getting submission error as expected output is not the same as the produced output
Wrong Answer
Your input
[2,4,3]
[5,6,4]
Output
[0,8]
Expected
[7,0,8]
I am assuming due to some reason, the first element is getting skipped. I would really appreciate an explanation of this problem is fixed.
It is just a simple summation between two numbers. The only thing we should add a dummy node as a starting point:
class Solution:
def add(self,l1:ListNode,l2:ListNode)->ListNode:
# it is a starter node
dummy = ListNode()
cur = dummy
carry = 0
# l1 or l2 is each digit
# since it is reversed, we start to sum the 1's place. that makes it easier
while l1 or l2 or carry:
v1 = l1.val if l1 else 0
v2 = l2.val if l2 else 0
val = v1 + v2 + carry
# because we are adding digits, if it is 15 carry will be 1
carry = val // 10
val = val % 10
cur.next = ListNode(val)
# update pointers
cur = cur.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
return dummy.next
I added two methods to the ListNode class to help with debugging and testing (but are not required for the class Solution to work) :
def __str__(self) -> str: # for readability only
# could be made recursive
values = []
current = self
while True:
values.append(current.val)
if current.next is None:
break
else:
current = current.next
return repr(values)
def __eq__(self, other: object) -> bool: # for testing
if isinstance(other, ListNode):
return (self.val == other.val) and (self.next == other.next)
else:
raise NotImplementedError
Also, I created an handy function to create ListNodes from integers :
def make_into_a_list(n: int) -> ListNode:
assert n >= 0
if n < 10:
return ListNode(n)
else:
last_digit = n % 10
trunk = (n - last_digit) // 10 # integer division
return ListNode(val=last_digit, next=make_into_a_list(trunk))
assert str(make_into_a_list(0)) == "[0]"
assert str(make_into_a_list(4)) == "[4]"
assert str(make_into_a_list(10)) == "[0, 1]"
assert str(make_into_a_list(12)) == "[2, 1]"
assert str(make_into_a_list(100)) == "[0, 0, 1]"
assert str(make_into_a_list(123)) == "[3, 2, 1]"
So here is my solution :
class Solution(object):
def addTwoNumbers(self, l1, l2):
carry = 0
result_digits = []
while True:
if (l1 is not None) and (l2 is not None):
digits_sum = l1.val + l2.val + carry
if digits_sum >= 10:
carry = 1
digits_sum -= 10
result_digits.append(digits_sum)
l1 = l1.next
l2 = l2.next
elif (l1 is None) and (l2 is not None):
result_digits.append(l2.val + carry)
carry = 0
l2 = l2.next
elif (l1 is not None) and (l2 is None):
result_digits.append(l1.val + carry)
carry = 0
l1 = l1.next
else: # both are None
break
result = None
for digit in reversed(result_digits):
result = ListNode(val=digit, next=result)
return result
num1 = ListNode(2, ListNode(4, ListNode(3)))
num2 = ListNode(5, ListNode(6, ListNode(4)))
assert Solution().addTwoNumbers(num1, num2) == make_into_a_list(807)
I also have a recursive solution :
class Solution(object):
def addTwoNumbers(self, l1, l2):
if not hasattr(self, "carry"):
# used to store the carry information through the recursive calls,
# without changing the method signature nor the __init__ code
self.carry = 0
if (l1 is not None) and (l2 is not None):
digits_sum = l1.val + l2.val + self.carry
if digits_sum >= 10:
self.carry = 1
digits_sum -= 10
return ListNode(val=digits_sum, next=self.addTwoNumbers(l1.next, l2.next))
elif (l1 is None) and (l2 is not None):
val = l2.val + self.carry
self.carry = 0
return ListNode(val=val, next=self.addTwoNumbers(l1, l2.next))
elif (l1 is not None) and (l2 is None):
val = l1.val + self.carry
self.carry = 0
return ListNode(val=val, next=self.addTwoNumbers(l1.next, l2))
else:
return None
Gosh, it takes two days to solve! My brain melted guys. Summary:
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
sum_list = [1, 2, 3, 4]
sum_list_reversed = sum_list[::-1]
# Magic happens ->
linked_list = ListNode()
linked_list_last_node = linked_list
for i, j in enumerate(sum_list_reversed):
if i == 0:
linked_list_last_node.val = j
else:
linked_list_last_node.next = ListNode(val=j)
linked_list_last_node = linked_list_last_node.next
# reading linkedlist
for i in range(len(sum_list_reversed)):
print(vars(linked_list))
linked_list = linked_list.next
# {'val': 4, 'next': <__main__.ListNode object at 0x000001837B7FFB70>}
# {'val': 3, 'next': <__main__.ListNode object at 0x000001837B812F98>}
# {'val': 2, 'next': <__main__.ListNode object at 0x000001837B812FD0>}
# {'val': 1, 'next': None}

Linked list iteration running infinitely

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

What is the problem with this chained assignment?

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.

linked nodes in while loop. (add two numbers from LeetCode)

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.

Python change equaled object?

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

Categories