Linked list add two numbers - python

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

Related

Reverse a sub list

I have to reverse a sub list in my linked list and then return the original linked list but with the sublist reversed. The question is as follows...
Given the head of a LinkedList and two positions ‘p’ and ‘q’, reverse the LinkedList from position ‘p’ to ‘q’.
For example
1 -> 2 -> 3 -> 4 -> 5 -> null, p = 2, q = 4 then,
1 -> 4 -> 3 -> 2 -> 5 -> null
from __future__ import print_function
class Node:
def __init__(self, value, next=None):
self.value = value
self.next = next
def print_list(self):
temp = self
while temp is not None:
print(temp.value, end=" ")
temp = temp.next
print()
def reverse_sub_list(head, p, q):
start, end = head, head
previous = None
while p > 1:
previous = start
start = start.next
p -= 1
while q > 0:
end = end.next
q -= 1
last_node_of_sub_list = start
sub_list = reverse(start, end)
previous.next = sub_list
last_node_of_sub_list.next = end
return head
'''
first_list = head
last_list = end
while first_list is not None:
first_list = first_list.next
first_list = sub_list
while sub_list is not None:
sub_list = sub_list.next
sub_list = last_list
return head
'''
def reverse(head, last_node):
previous = None
while head is not last_node:
_next = head.next
head.next = previous
previous = head
head = _next
return previous
def main():
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
head.next.next.next.next = Node(5)
print("Nodes of original LinkedList are: ", end='')
head.print_list()
result = reverse_sub_list(head, 2, 4)
print("Nodes of reversed LinkedList are: ", end='')
result.print_list()
main()
In my while loops I thought I was connecting the last node of the first_list to sub_list and the last node of sub_list to the last_list.
Turns out that when I return head, head is now only 1 -> 2 -> null
This happens when I reverse the sub_list which is fine and I understand that part, but I thought I was reconnecting my lists again.
def reverse_sub_list(head, p, q):
start, end = head, head
previous = None
while p > 1:
previous = start
start = start.next
p -= 1
Now before moving with q > 0 while loop, you can just store the values of the previous and current and continue with q > 0 while loop.
And inside this loop, the reverse is done and q is decremented
connection = previous
tail = current
while q > 0:
currentNext = current.next
current.next = previous
previous = current
current = currentNext
q--
Now all we have got is whether connection was null or not. If the connection is null, then you can set previous to head else set previous to connection.next
if connection != None:
connection.next = previous
else:
head = previous
tail.next = current
return head
Full Code :
def reverse_sub_list(head, p, q):
current = head
previous = None
while p > 1:
previous = start
current = current.next
p -= 1
connection = previous
tail = current
while q > 0:
currentNext = current.next
current.next = previous
previous = current
current = currentNext
q--
if connection != None:
connection.next = previous
else:
head = previous
tail.next = current
return head
You can check this link for more explanation and figure : Click here
https://leetcode.com/problems/reverse-linked-list-ii/description/
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
if left == right:
return head
prev = start = prev_start = None
node = head
for count in range(1, right + 1):
if count >= left:
if not start:
prev_start = prev
start = node
nxt = node.next
node.next = prev
prev = node
node = nxt
else:
prev = node
node = node.next
if prev_start:
prev_start.next = prev
if start:
start.next = node
return head if left > 1 else prev

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

Intersection of two sorted Linked lists in python3?

My code is unable two print out the new list which is the intersection of two sorted linked list.Its not able to access list inside the function. Please point out the mistake in my code. there is no indentation problem in my code and the algorithm also seems to be fine.
class Node(object):
def __init__(self,data):
self.data = data
self.next = None
class Linked(object):
def __init__(self):
self.head = None
def push(self,n):
new_node = Node(n)
new_node.next = self.head
self.head = new_node
def print_list(self):
current = self.head
while current:
print(current.data)
current = current.next
def intersect(self,l1,l2):
l1 = l1.head
l2 = l2.head
dummy = cur = Node(0)
while l1 and l2:
if l2.data>l1.data:
l1=l1.next
elif l1.data>l2.data:
l2=l2.next
else:
cur.next = l1 or l2
l1 = l1.next
l2 = l2.next
cur = cur.next
return dummy.next
llist = Linked()
llist1 = Linked()
llist.push(6)
llist.push(4)
llist.push(3)
llist.push(2)
llist.push(1)
llist1.push(8)
llist1.push(6)
llist1.push(4)
llist1.push(2)
l = Linked()
print(l.intersect(llist,llist1).data)
Here is the traceback:
Traceback (most recent call last):
File "C:/Users/omsai/Desktop/intersection.py", line 48, in <module>
print(l.intersect(llist,llist1).data)
File "C:/Users/omsai/Desktop/intersection.py", line 26, in intersect
if l2.data>l1.data:
AttributeError: 'Linked' object has no attribute 'data'
You're calling Linked.intersect with two instances of Linked, which doesn't have a data member. You need to get the actual nodes out in the intersect method:
def intersect(self,l1,l2):
l1 = l1.head
l2 = l2.head
dummy = cur = Node(0)
# ...
You probably don't need to call intersect with two arguments; it would be enough to intersect one list against another:
def intersect(self, olinked):
thisone = self.head
otherone = olinked.head
retval = Linked()
while thisone and otherone:
if otherone.data > thisone.data:
thisone = thisone.next
elif thisone.data > otherone.data:
otherone = otherone.next
else: # thisone.data == otherone.data
retval.push(otherone.data)
thisone = thisone.next
otherone = otherone.next
return retval
# ...
llist.intersect(llist1).print_list()

Categories