Linked list iteration running infinitely - python

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

Related

Linked list add two numbers

Any idea why the summation is returning zero , currently trying to add linked list sum , in leetcode its working fine , however while trying for complete solution it's creating error
Problem from leetcode -
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.
Added couple of examples -
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
Input: l1 = [0], l2 = [0]
Output: [0]
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
class Node:
def __init__(self , data=0,next=None):
self.data=data
self.next=next
class solution:
def __init__(self) -> None:
self.head = None
def insert_at_begining (self,data):
node = Node(data,self.head)
self.head = node
def print(self):
if self.head is None:
print ("Linked list is empty")
return
listr = ''
itr = self.head
while itr:
listr += str(itr.data) + "-->"
itr = itr.next
print (listr)
def revereList(self):
prev , curr = None , self.head
while curr:
tmp =curr.next
curr.next = prev
prev = curr
curr = tmp
self.head= prev
def merge_sorted_upd(self, llist):
p = self.head
q = llist.head
dummy = Node()
tail = dummy
while p and q:
if p.data <= q.data:
tail.next = p
p = p.next
else:
tail.next = q
q = q.next
tail = tail.next
if p:
tail.next = p
if q:
tail.next = q
return dummy.next
def lp_add_two_numbers(self,p,q):
##first create a dummy node
prev=None
dummy = Node()
cur=dummy
carry = 0
l1 = p.head
l2 = q.head
while l1 or l2 :
v1 = l1.data if l1 else 0
v2 = l2.data if l2 else 0
val = v1 + v2 + carry
val = val % 10
carry = val/10
cur.next = Node(val)
if self.head is None:
self.head = cur
else:
dummy.next = cur
dummy=cur
cur = cur.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
return dummy.next
if __name__=='__main__':
l1=solution()
l1.insert_at_begining(4)
l1.insert_at_begining(2)
l1.insert_at_begining(1)
l1.print()
l2=solution()
l2.insert_at_begining(7)
l2.insert_at_begining(6)
l2.insert_at_begining(5)
l2.print()
# l1.merge_sorted_upd(l2)
# l1.print()
res=solution()
res.lp_add_two_numbers(l1 , l2)
res.print()
output coming as
1-->2-->4-->
5-->6-->7-->
0 6 8.6 1.8599999999999994

(Python) Summing two linked lists where each node is an integer. Attribute error

class Node:
def __init__(self, data = None, next = None):
self.data = data
self.next = next
class LinkedList:
def __init__(self, node = None):
self.head = node
self.length = 0
def InsertNode(self, data):
newNode = Node()
newNode.data = data
if self.length == 0:
self.head = newNode
else:
newNode.next = self.head
self.head = newNode
self.length += 1
def printList(self):
temp = self.head
while temp != None:
print(temp.data, end = " ")
temp = temp.next
class AddingListNumbers:
def addTwoNumbers(self, list1, list2):
if list1 == None:
return list2
if list2 == None:
return list1
len1 = len2 = 0
head = list1.head
while head != None:
len1 += 1
head = head.next
head = list2.head
while head != None:
len2 += 1
head = head.next
if len1 > len2:
shorter = list2
longer = list1
else:
shorter = list1
longer = list2
sum = None
carry = 0
while shorter != None:
value = shorter.data + longer.data + carry
carry = value / 10
value -= carry * 10
if sum == None:
sum = Node(value)
result = sum
else:
sum.next = Node(value)
sum = sum.next
shorter = shorter.next
longer = longer.next
while longer != None:
value = longer.data + carry
carry = value / 10
value -= carry * 10
sum.next = Node(value)
sum = sum.next
longer = longer.next
if carry != 0:
sum.next = Node(carry)
return result
linkedlist = LinkedList()
linkedlist.InsertNode(19)
linkedlist.InsertNode(14)
linkedlist.InsertNode(11)
linkedlist.InsertNode(9)
linkedlist.InsertNode(6)
linkedlist.InsertNode(5)
linkedlist2 = LinkedList()
linkedlist2.InsertNode(17)
linkedlist2.InsertNode(16)
linkedlist2.InsertNode(13)
linkedlist2.InsertNode(6)
linkedlist2.InsertNode(2)
linkedlist2.InsertNode(1)
linkedlist2.InsertNode(24)
linkedlist2.InsertNode(3)
linkedlist2.InsertNode(11)
list3 = LinkedList()
ResultList = AddingListNumbers()
list3.next = ResultList.addTwoNumbers(linkedlist, linkedlist2)
list3.printList()
I have created Node and LinkedList classes and then another class AddingListNumbers for adding the list number.
I am getting an error message:
value = shorter.data + longer.data + carry
AttributeError: 'LinkedList' object has no attribute 'data'
I don't understand how to debug this one. How to handle attribute errors?
Below is the image of the error message.
The issue is with this section:
if len1 > len2:
shorter = list2 # should be list2.head instead
longer = list1 # should be list1.head instead
else:
shorter = list1 # should be list1.head instead
longer = list2 # should be list2.head instead
With that said, however, this code can be optimised to traverse the lists only once. In this implementation you're first finding the shorter list and then adding while the shorter list is traversed. It can be done in single traversal as:
Repeat these steps while list1 is traversed OR list2 is traversed completely
Add data from node of list1, if it exists, or add 0
Add data from node of list2, if it exists, or add 0
Add carry to the above sum.
Calculate divmod of the sum and re-assign carry and sum.
Move pointers ahead, if next nodes are present.
The resultant list will have sum of the lists.

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 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.

single linked list reverse in python

i'm trying to create a simple single linked list in python.
(i know there is no need to implement list in python, but that's not the point)
here is my code:
class Node:
def __init__(self,data):
self.data = data
self.next= None
class List:
def __init__(self):
self.firstNode = Node(None)
def inserthead(self,newnode):
if not self.firstNode.next:
newnode.next = None
self.firstNode.next = newnode
else:
newnode.next = self.firstNode.next
self.firstNode.next= newnode
def __show(self,start):
if start.next:
print start.data
self.__show(start.next)
def printlist(self):
self.__show(self.firstNode)
def __reverte_recursive(self,node):
temp = None
if not node.next: return node
else:
temp = self.__reverte_recursive(node.next)
node.next.next= node
node.next = None
return temp
def reverte_list1(self):
self.firstNode=self.__reverte_recursive(self.firstNode)
def __reverte_iterative(self,node):
temp = None
previous = None
while node and node.next:
temp = node.next
node.next= previous
previous = node
node = temp
return previous
def reverte_iterative(self):
self.firstNode=self.__reverte_iterative(self.firstNode)
nodeA = Node("A")
nodeB = Node("B")
nodeC = Node("C")
nodeD = Node("D")
nodeE = Node("E")
list1= List()
list1.inserthead(nodeA)
list1.inserthead(nodeB)
class Node:
def __init__(self,data):
self.data = data
self.next= None
class List:
def __init__(self):
self.firstNode = Node(None)
def inserthead(self,newnode):
if not self.firstNode.next:
newnode.next = None
self.firstNode.next = newnode
else:
newnode.next = self.firstNode.next
self.firstNode.next= newnode
def __show(self,start):
if start.next:
print start.data
self.__show(start.next)
def printlist(self):
self.__show(self.firstNode)
def __reverte_recursive(self,node):
temp = None
if not node.next: return node
else:
temp = self.__reverte_recursive(node.next)
node.next.next= node
node.next = None
return temp
def reverte_list1(self):
self.firstNode=self.__reverte_recursive(self.firstNode)
def __reverte_iterative(self,node):
temp = None
previous = None
while node and node.next:
temp = node.next
node.next= previous
previous = node
node = temp
return previous
def reverte_iterative(self):
self.firstNode=self.__reverte_iterative(self.firstNode)
nodeA = Node("A")
nodeB = Node("B")
nodeC = Node("C")
nodeD = Node("D")
nodeE = Node("E")
list1= List()
list1.inserthead(nodeA)
list1.inserthead(nodeB)
list1.inserthead(nodeC)
list1.inserthead(nodeD)
list1.inserthead(nodeE)
print "list"
list1.printlist()
print "list reverse"
list1.reverte_list1()
list1.printlist()
list1.reverte_iterative()
print "list reverse reverse"
list1.printlist()
and there are the result:
None
E
D
C
B
list reverse
A
B
C
D
E
list reverse reverse
E
D
C
B
for some reason i can't print all the list and in the first case doesn't print the "A" Node
but print the first node(but i checkd and the B node points to A)
the first reverse is OK
but the third again don't print the A node even if it's pointed by the B Node.
probably the problem of the printing is in the __show function.
but i suppose i a conceptual bug.
thanks
def __show(self,start):
if start.next:
print start.data
self.__show(start.next)
that only prints the current node if it has a next node, thats why the last node is never printed.
should be:
def __show(self,start):
if start:
print start.data
self.__show(start.next)
you make similar mistakes of checking/assigning a node instead of it's next and vice versa throughout the code (in inserthead() for example - which is causing the None being printed)

Categories