medium Add Two Numbers
Problem Statement
You are given two non-empty linked lists that represent two non-negative integers, where each node contains the single digit. The digits are stored in reverse order. Add these two numbers and return the sum as a linked list.
You can assume the numbers do not have leading zeros, except for the number 0 itself.
Examples
Example 1:
- Input: l1: [1, 2, 3], l2: [4, 5, 6]
- Expected Output: [5, 7, 9]
- Justification: 321 + 654 = 975, which in reverse order is [5, 7, 9].
Example 2:
- Input: l1: [7, 8], l2: [6, 7, 8, 9]
- Expected Output: [3, 6, 9, 9]
- Justification: 87 + 9876 = 9963, which in reverse order is [3, 6, 9, 9].
Example 3:
- Input: l1: [0], l2: [0]
- Expected Output: [0]
- Justification: 0 + 0 = 0, which in reverse order is [0].
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.
Try it yourself
Try solving this question here:
✅ Solution Add Two Numbers
Problem Statement
You are given two non-empty linked lists that represent two non-negative integers, where each node contains the single digit. The digits are stored in reverse order. Add these two numbers and return the sum as a linked list.
You can assume the numbers do not have leading zeros, except for the number 0 itself.
Examples
Example 1:
- Input: l1: [1, 2, 3], l2: [4, 5, 6]
- Expected Output: [5, 7, 9]
- Justification: 321 + 654 = 975, which in reverse order is [5, 7, 9].
Example 2:
- Input: l1: [7, 8], l2: [6, 7, 8, 9]
- Expected Output: [3, 6, 9, 9]
- Justification: 87 + 9876 = 9963, which in reverse order is [3, 6, 9, 9].
Example 3:
- Input: l1: [0], l2: [0]
- Expected Output: [0]
- Justification: 0 + 0 = 0, which in reverse order is [0].
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
To solve this problem, we will iterate through both linked lists while adding corresponding digits along with any carry from the previous addition. We'll start from the least significant digit (head of the list). If the sum of the digits and carry is 10 or more, we'll set the current node value to the remainder when divided by 10 and carry forward the quotient. This approach ensures that we handle all digit additions and carries correctly as we move through the lists.
This approach works well because it mimics the manual addition process, dealing with each digit and carrying over values as needed. It efficiently handles linked lists of different lengths by continuing to process the longer list once the shorter one is exhausted, ensuring that all digits are accounted for in the final sum.
Step-by-Step Algorithm
- Initialize a dummy node to act as the starting point of the result linked list.
- Set a pointer
currentto this dummy node. - Initialize a variable
carryto 0. - Loop through the lists until both are exhausted:
- Sum the current digits of both lists and the
carry. - Update
carryto be the floor division of the sum by 10. - Set the next node's value to the sum modulo 10.
- Move the
currentpointer to the next node. - Move to the next node in each input list if available.
- Sum the current digits of both lists and the
- After the loop, if
carryis not zero, add a new node with thecarryvalue. - Return the next node of the dummy node as the head of the result linked list.
Algorithm Walkthrough
Let's walk through the algorithm step-by-step with the input l1: [7, 8] and l2: [6, 7, 8, 9].
-
Initialization:
- Create a dummy node to act as the head of the result list.
- Set a
currentpointer to the dummy node. - Initialize a
carryvariable to 0.
-
First Iteration:
- Add the values of the first nodes of
l1andl2, plus the carry:sum = 7 (l1) + 6 (l2) + 0 (carry) = 13
- Calculate the new carry and the digit to store in the result list:
carry = 13 // 10 = 1current.next = new ListNode(13 % 10) = new ListNode(3)
- Move the
currentpointer to the next node:current = current.next
- Move to the next nodes in
l1andl2:l1 = l1.next (8)l2 = l2.next (7)
- Add the values of the first nodes of
-
Second Iteration:
- Add the values of the current nodes of
l1andl2, plus the carry:sum = 8 (l1) + 7 (l2) + 1 (carry) = 16
- Calculate the new carry and the digit to store in the result list:
carry = 16 // 10 = 1current.next = new ListNode(16 % 10) = new ListNode(6)
- Move the
currentpointer to the next node:current = current.next
- Move to the next nodes in
l1andl2:l1 = l1.next (null)l2 = l2.next (8)
- Add the values of the current nodes of
-
Third Iteration:
- Add the values of the current node of
l2(sincel1is null), plus the carry:sum = 0 (l1 is null) + 8 (l2) + 1 (carry) = 9
- Calculate the new carry and the digit to store in the result list:
carry = 9 // 10 = 0current.next = new ListNode(9 % 10) = new ListNode(9)
- Move the
currentpointer to the next node:current = current.next
- Move to the next node in
l2:l2 = l2.next (9)
- Add the values of the current node of
-
Fourth Iteration:
- Add the values of the current node of
l2(sincel1is null), plus the carry:sum = 0 (l1 is null) + 9 (l2) + 0 (carry) = 9
- Calculate the new carry and the digit to store in the result list:
carry = 9 // 10 = 0current.next = new ListNode(9 % 10) = new ListNode(9)
- Move the
currentpointer to the next node:current = current.next
- Move to the next node in
l2:l2 = l2.next (null)
- Add the values of the current node of
-
Final Step:
- Both
l1andl2are now null, and the carry is 0, so we don't need to add any more nodes.
- Both
-
Return the Result:
- Return the node next to the dummy node as the head of the result list.
The final result is the linked list [3, 6, 9, 9].
Code
// Definition for singly-linked list
// class ListNode {
// int val;
// ListNode next;
// ListNode(int x) { val = x; }
// }
class Solution {
// Method to add two numbers represented by linked lists
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0); // Dummy node to start the result list
ListNode current = dummy; // Pointer to the current node in the result list
int carry = 0; // Initialize carry to 0
// Loop through lists l1 and l2 until both are null
while (l1 != null || l2 != null) {
int sum = carry; // Start with the carry from the previous iteration
if (l1 != null) {
sum += l1.val; // Add l1's value to sum
l1 = l1.next; // Move to the next node in l1
}
if (l2 != null) {
sum += l2.val; // Add l2's value to sum
l2 = l2.next; // Move to the next node in l2
}
carry = sum / 10; // Calculate new carry
current.next = new ListNode(sum % 10); // Create new node with the sum modulo 10
current = current.next; // Move to the next node in the result list
}
// If carry is still greater than 0, add a new node with carry value
if (carry > 0) {
current.next = new ListNode(carry);
}
return dummy.next; // Return the result list
}
// Helper method to print linked list
private static void printList(ListNode node) {
while (node != null) {
System.out.print(node.val + " ");
node = node.next;
}
System.out.println();
}
// Main method to test the solution with provided examples
public static void main(String[] args) {
Solution solution = new Solution();
// Example 1
ListNode l1 = new ListNode(1);
l1.next = new ListNode(2);
l1.next.next = new ListNode(3);
ListNode l2 = new ListNode(4);
l2.next = new ListNode(5);
l2.next.next = new ListNode(6);
ListNode result = solution.addTwoNumbers(l1, l2);
printList(result); // Expected output: 5 7 9
// Example 2
l1 = new ListNode(7);
l1.next = new ListNode(8);
l2 = new ListNode(6);
l2.next = new ListNode(7);
l2.next.next = new ListNode(8);
l2.next.next.next = new ListNode(9);
result = solution.addTwoNumbers(l1, l2);
printList(result); // Expected output: 3 6 9 9
// Example 3
l1 = new ListNode(0);
l2 = new ListNode(0);
result = solution.addTwoNumbers(l1, l2);
printList(result); // Expected output: 0
}
}
Complexity Analysis
- Time Complexity:
, where mandnare the lengths of the two input linked lists. We iterate through both lists once. - Space Complexity:
. We create a new linked list that holds the sum of the input linked lists, which could be as long as the longer input list plus one extra node for a possible carry.
🤖 Don't fully get this? Learn it with Claude
Stuck on Add Two Numbers? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Add Two Numbers** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Add Two Numbers** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Add Two Numbers**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Add Two Numbers**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.