You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each node contains a single digit. Add the two numbers and return the sum as a linked list (also in reverse order).
โข 1 โค number of nodes โค 100โข 0 โค Node.val โค 9โข No leading zeros (except the number 0 itself)
02
Section Two ยท Approach 1
Convert to Integer โ Overflow risk
Convert both lists to integers, add, then convert the result back to a list. Simple but fails for numbers exceeding integer range (up to 100 digits!).
Problem: 100-digit numbers overflow any integer type. The digit-by-digit approach handles arbitrarily long numbers naturally, just like manual addition on paper.
03
Section Three ยท Approach 2
Digit-by-Digit Addition โ O(max(m, n))
Add corresponding digits from both lists plus the carry. Store the ones digit in a new node, propagate the tens digit as carry. Continue until both lists and carry are exhausted.
๐ก Mental model: Elementary school long addition. Start from the rightmost digit (which is conveniently the head, since digits are reversed). Add two digits + carry. Write down the ones place, carry the tens place. Move left. This is exactly what we're doing node by node.
Algorithm
Step 1: Create a dummy node and a tail pointer. carry = 0.
Step 2: While l1 or l2 or carry > 0:
Sum = (l1.val or 0) + (l2.val or 0) + carry.
carry = sum / 10. digit = sum % 10.
Create new node with digit, link it.
Advance l1, l2 if not null.
Step 3: Return dummy.next.
๐ฏ Why reverse order helps:
Digits are stored least-significant first โ exactly the order we need for addition. No reversal required.
We start adding from the ones place naturally.
04
Section Four ยท Trace
Visual Walkthrough
Trace: l1 = 2โ4โ3, l2 = 5โ6โ4:
Digit-by-digit addition with carry
05
Section Five ยท Implementation
Code โ Java & Python
Java โ Digit-by-digit
classSolution {
publicListNodeaddTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = newListNode(0);
ListNode tail = dummy;
int carry = 0;
while (l1 != null || l2 != null || carry != 0) {
int sum = carry;
if (l1 != null) { sum += l1.val; l1 = l1.next; }
if (l2 != null) { sum += l2.val; l2 = l2.next; }
carry = sum / 10;
tail.next = newListNode(sum % 10);
tail = tail.next;
}
return dummy.next;
}
}
Python โ Digit-by-digit
classSolution:
defaddTwoNumbers(self, l1, l2):
dummy = tail = ListNode(0)
carry = 0while l1 or l2 or carry:
s = carry
if l1: s += l1.val; l1 = l1.next
if l2: s += l2.val; l2 = l2.next
carry, digit = divmod(s, 10)
tail.next = ListNode(digit)
tail = tail.next
return dummy.next
06
Section Six ยท Analysis
Complexity Analysis
Approach
Time
Space
Trade-off
Digit-by-digit โ optimal
O(max(m,n))
O(max(m,n))
One pass, handles any length. Space for output list.
07
Section Seven ยท Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
Different lengths
9โ9โ9 + 9โ9
Shorter list runs out first โ treat missing digits as 0.
Final carry
9โ9 + 1 = 0โ0โ1
Result is longer than both inputs. The || carry condition handles this.
Zero
0 + 0
0+0+0=0, carry=0 โ single node [0].
โ Common Mistake: Forgetting to check carry != 0 in the loop condition. If both lists end but carry is 1 (e.g., 99+1=100), you miss the leading 1. Always include carry in the termination condition.