Add Two Numbers II
Problem Descriptionβ
You are given two non-empty
linked lists representing two non-negative integers. The most significant digit comes first 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.
Examplesβ
Example 1:
Input: l1 = [7,2,4,3], l2 = [5,6,4]
Output: [7,8,0,7]
Example 2:
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [8,0,7]
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.
Solution for Add Two Numbers IIβ
Approach 1: Reverse Given Linked Listsβ
Intuitionβ
We are told that the most significant digit comes first, and that each of their nodes includes a single digit. To do a basic addition of two numbers using a sum of two digits and a carry, we must start with the least significant digits (the lowest place) and work our way up to the most significant digits.
To get the order of digits from the least significant digits to the the most significant digits, we can reverse the given lists so the least significant digits come first.
We can then iterate over the reversed lists to perform the addition of digits at corresponding places similar to the first approach.
Let's understand how to reverse a linked list.
To reverse a linked list, we need three pointers. The first pointer head
points to the current node under consideration, temp
points to the next node, and prev
points to the previous node. This is because while traversing the list, we change the current node's (head
) next pointer to point to its previous element (prev
). Since a node does not have reference to its previous node, we must store its previous element beforehand. We also need another pointer to store the next node (temp
) before changing the reference so we don't lose it after changing head.next
.
We start with initializing prev
to null
. We then loop until head
is null, i.e., until we iterate over all the elements. We store head.next
in temp
to store the next node we will go to. After storing the next node, we reverse next
of head
to the previous element, i.e., head.next = prev
. We then move prev
to head
as this becomes the previous node for the next node and also move head
to temp
as this becomes the new node under consideration.
Algorithmβ
- Create two linked lists
r1
andr2
to store the reverse of the linked listsl1
andl2
respectively. - Create two integers
totalSum
andcarry
to store the sum and carry of current digits. - Create a new
ListNode
,ans
that will store the sum of current digits. - We will add the two numbers using the reverse list by adding the digits one by one. We continue until we cover all the nodes in
r1
andr2
:- If
r1
is not null, we addr1.val
tototalSum
. - If
r2
is not null, we addr2.val
tototalSum
. - Set `ans.val = totalSum % 10.
- Store the
carry
astotalSum / 10
. - Create a new
ListNode
,newNode
that will haveval
ascarry
. Setnext
ofnewNode
toans
. Updateans = newNode
to use the same variableans
for the next iteration. - Update
totalSum = carry
.
- If
- If
carry == 0
, it means the newNode that we created in the final iteration of while loop hasval = 0
. Because we performans = newNode
at the end of each while loop iteration while loop, to avoid returning a linked list with a head of0
(leading zero), we return the next element, i.e., we returnans.next
. Otherwise, ifcarry
is not equal to0
, the value ofans
is non-zero. Hence, we just returnans
.
Code in Different Languagesβ
- C++
- Java
- Python
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* temp;
while (head) {
// Keep the next node.
temp = head->next;
// reverse the link
head->next = prev;
// Update the previous node and the current node.
prev = head;
head = temp;
}
return prev;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* r1 = reverseList(l1);
ListNode* r2 = reverseList(l2);
int totalSum = 0;
int carry = 0;
ListNode* ans = new ListNode();
while (r1 || r2) {
if (r1) {
totalSum += r1->val;
r1 = r1->next;
}
if (r2) {
totalSum += r2->val;
r2 = r2->next;
}
ans->val = totalSum % 10;
carry = totalSum / 10;
ListNode* head = new ListNode(carry);
head->next = ans;
ans = head;
totalSum = carry;
}
return carry == 0 ? ans->next : ans;
}
};
public class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null, temp;
while (head != null) {
// Keep the next node
temp = head.next;
// Reverse the link
head.next = prev;
// Update the previous node and the current node.
prev = head;
head = temp;
}
return prev;
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode r1 = reverseList(l1);
ListNode r2 = reverseList(l2);
int totalSum = 0, carry = 0;
ListNode ans = new ListNode();
while (r1 != null || r2 != null) {
if (r1 != null) {
totalSum += r1.val;
r1 = r1.next;
}
if (r2 != null) {
totalSum += r2.val;
r2 = r2.next;
}
ans.val = totalSum % 10;
carry = totalSum / 10;
ListNode head = new ListNode(carry);
head.next = ans;
ans = head;
totalSum = carry;
}
return carry == 0 ? ans.next: ans;
}
}
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
temp = None
while head:
# Keep the next node
temp = head.next
# Reverse the link
head.next = prev
# Update the previous node and the current node.
prev = head
head = temp
return prev
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
r1 = self.reverseList(l1)
r2 = self.reverseList(l2)
total_sum = 0
carry = 0
ans = ListNode()
while r1 or r2:
if r1:
total_sum += r1.val
r1 = r1.next
if r2:
total_sum += r2.val
r2 = r2.next
ans.val = total_sum % 10
carry = total_sum // 10
head = ListNode(carry)
head.next = ans
ans = head
total_sum = carry
return ans.next if carry == 0 else ans