Python Algorithm Q16
Q16 Add Two Numbers
Q
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.
Sample Input
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
Input: l1 = [0], l2 = [0]
Output: [0]
Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]
Constraints
- The number of nodes in each linked list is in the range
[1, 100]
. - 0 <= Node.val <= 9
- It is guaranteed that the list represents a number that does not have leading zeros.
1. My own Solution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
ls1, ls2, finls = [], [], [] #define empty list
while l1:
ls1.append(l1.val)
l1 = l1.next
while l2:
ls2.append(l2.val)
l2 = l2.next
#finish conversion to the list
ls1.reverse()
ls2.reverse()
#finish reversing
lstsum = int(''.join(map(str, ls1))) + int(''.join(map(str, ls2)))
#finish adding
if lstsum == 0:
finls.append(0)
#exception - when both are 0
while lstsum >= 1:
left = lstsum%10
finls.append(left)
lstsum = lstsum//10
#finish creating list consist of reversed number
AnsNode = ListNode()
head = AnsNode
for val in finls:
next = ListNode(val)
AnsNode.next = next
AnsNode = AnsNode.next
return head.next
[Conversion to the List]
My solution is really simple. Just change linked list into the list, and then calculate. Therefore, my code is too much longer than the given one. Also, the run time is almost the worst… Execution time is the bottom 5%… ㅠㅠ Maybe no explanation is needed. My answer is really intuitive and easy to read.
2. Given Solution #1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution:
#reversing linked-list
def reverseList(self, head: ListNode) -> ListNode:
node, prev = head, None
while node:
next, node.next = node.next, prev
prev, node = node, next
return prev
#divert linked-list to list
def toList(self, node: ListNode) -> List:
list: List = []
while node:
list.append(node.val)
node = node.next
return list
# List to linked-list
def toReversedLinkedList(self, result: str) -> ListNode:
prev: ListNode = None
for r in result:
node = ListNode(r)
node.next = prev
prev = node
return node
#add to linked-list with the functions above
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
a = self.toList(self.reverseList(l1))
b = self.toList(self.reverseList(l2))
resultStr = int(''.join(str(e) for e in a)) + int(''.join(str(e) for e in b))
return self.toReversedLinkedList(str(resultStr))
Almost same as mine. Simply divided my codes into many functions. Skip explanation.
3. Given Solution #2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
root = head = ListNode(0)
carry = 0
while l1 or l2 or carry:
#until l1 or l2 exists, or when CARRY IN EXISTS so need to expand the digit.
sum = 0 #initialize sum every loop
#sum each digits(자릿수) if that node exists.
if l1:
sum+=l1.val
l1 = l1.next
if l2:
sum+=l2.val
l2 = l2.next
#divmod returns the tuple of quotient and remainder.
carry, val = divmod(sum+carry, 10) #from the previous digit, CI(carry in) can be 0 or 1
head.next = ListNode(val)
head = head.next
return root.next
This is the solution using the “full-adder”. This derived from the concept that “How about adding each digit instead of converting linked-list to list.”
Overall Review
Not that hard problem. But with my solution, codes are so messed up because of many steps.
- Conversion from Linked-list to list
- Joining list elements to the single variable
- Make it integer type then add each other
- Convert the result to the linked-list
However, given sol #2 is very interesting. I just vaguely thought how about adding linked-list value itself by considering carry in, rather than following the complicated steps above. But I cannot realize my idea of embodying carry in. Using full-adder is the perfect solution to actualize the digit operation. There is no ending in learning CS…