Skip to content

Add Two Numbers

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 in the same reverse order.

l1l2OutputExplanation
[2, 4, 3][5, 6, 4][7, 0, 8]342 + 465 = 807 (reversed)
[0][0][0]0 + 0 = 0
[9,9,9,9,9,9,9][9,9,9,9][8,9,9,9,0,0,0,1]9999999 + 9999 = 10009998 (reversed)
  • 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.
ApproachTimeSpaceCall StackBest When
IterativeO(max(m, n))O(max(m, n))MinimalGeneral case — clean, no recursion overhead
RecursiveO(max(m, n))O(max(m, n))O(max(m, n))Learning recursion, practicing self-similar structure

* Space refers to output list size. Both approaches handle carries efficiently.

  • Pick Iterative if you want the most straightforward, predictable solution.
  • Pick Recursive if you are practicing recursion or want to see how the problem mirrors itself at each digit.
Recommended
Iterative
O(max(m, n)) time · O(max(m, n)) space
Educational
Recursive
O(max(m, n)) time · O(max(m, n)) space
Section titled “Approach 1: Iterative with Carry (Recommended)”
★ Recommended

Walk through both lists simultaneously, adding digits column-by-column and propagating the carry forward.

Use a dummy node at the start to simplify list construction. At each step, compute the sum of the two digit values plus any carry from the previous step, extract the new carry, and create a new node for the result digit.

⏱ Time O(max(m, n)) One pass through lists 💾 Space O(max(m, n)) Output list size

Input: l1 = [2, 4, 3] (342), l2 = [5, 6, 4] (465)

Stepl1l2carrysumdigitnew_carryresult
1250770[7]
24601001[7, 0]
3341880[7, 0, 8]
Done--0---

Input: l1 = [9,9,9,9,9,9,9] (9999999), l2 = [9,9,9,9] (9999)

The carry propagates all the way through: 9999999 + 9999 = 10009998, which becomes [8,9,9,9,0,0,0,1] in reverse.

Animated walkthrough

How carry propagation works through digit-by-digit addition

Use Next or Autoplay to watch the algorithm process each digit, compute the sum with carry, and build the result list.

Step 1 of 3 Target: max(m, n)
Waiting to begin...
Array state
Memory / lookup state

function addTwoNumbers(l1, l2):
dummy = ListNode(0)
current = dummy
carry = 0
while l1 or l2 or carry:
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0
total = val1 + val2 + carry
carry = total / 10
digit = total % 10
current.next = ListNode(digit)
current = current.next
l1 = l1.next if l1 else null
l2 = l2.next if l2 else null
return dummy.next
add_two_numbers_iterative.py
from typing import Optional
class ListNode:
def __init__(self, val: int = 0, next: Optional['ListNode'] = None):
self.val = val
self.next = next
def addTwoNumbers(l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
"""
Add two numbers represented by linked lists in reverse order.
Time Complexity: O(max(m, n)) where m and n are the lengths of the lists
Space Complexity: O(max(m, n)) for the output list
"""
dummy = ListNode(0)
current = dummy
carry = 0
while l1 or l2 or carry:
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0
total = val1 + val2 + carry
carry = total // 10
digit = total % 10
current.next = ListNode(digit)
current = current.next
l1 = l1.next if l1 else None
l2 = l2.next if l2 else None
return dummy.next
# Test cases
if __name__ == "__main__":
# Helper function to create linked list from list
def create_linked_list(arr):
if not arr:
return None
head = ListNode(arr[0])
current = head
for val in arr[1:]:
current.next = ListNode(val)
current = current.next
return head
# Helper function to convert linked list to list for printing
def linked_list_to_list(head):
result = []
current = head
while current:
result.append(current.val)
current = current.next
return result
# Test case 1: [2,4,3] + [5,6,4] = [7,0,8] (342 + 465 = 807)
l1 = create_linked_list([2, 4, 3])
l2 = create_linked_list([5, 6, 4])
result = addTwoNumbers(l1, l2)
print(f"Test 1: {linked_list_to_list(result)}") # [7, 0, 8]
# Test case 2: [0] + [0] = [0]
l1 = create_linked_list([0])
l2 = create_linked_list([0])
result = addTwoNumbers(l1, l2)
print(f"Test 2: {linked_list_to_list(result)}") # [0]
# Test case 3: [9,9,9,9,9,9,9] + [9,9,9,9] = [8,9,9,9,0,0,0,1] (9999999 + 9999 = 10009998)
l1 = create_linked_list([9, 9, 9, 9, 9, 9, 9])
l2 = create_linked_list([9, 9, 9, 9])
result = addTwoNumbers(l1, l2)
print(f"Test 3: {linked_list_to_list(result)}") # [8, 9, 9, 9, 0, 0, 0, 1]
educational

Let the recursion handle the “advance to next digit” logic. At each recursive call, add the current digits plus the carry, extract the new carry, and recursively build the rest of the list.

The base case occurs when both lists are exhausted and the carry is zero.

⏱ Time O(max(m, n)) One pass through lists 💾 Space O(max(m, n)) Call stack + output

Input: l1 = [2, 4, 3], l2 = [5, 6, 4]

The recursion mirrors the iterative solution:

  • Call 1: helper(2, 5, 0) → sum=7, digit=7, carry=0 → create node(7) and recurse
  • Call 2: helper(4, 6, 0) → sum=10, digit=0, carry=1 → create node(0) and recurse
  • Call 3: helper(3, 4, 1) → sum=8, digit=8, carry=0 → create node(8) and recurse
  • Call 4: helper(null, null, 0) → base case, return null
  • Build result bottom-up: 7 → 0 → 8 → null

The recursion naturally builds the list in the correct order because we construct each node after the recursive call returns.

function addTwoNumbers(l1, l2):
return helper(l1, l2, 0)
function helper(l1, l2, carry):
if not l1 and not l2 and carry == 0:
return null
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0
total = val1 + val2 + carry
digit = total % 10
newCarry = total / 10
nextL1 = l1.next if l1 else null
nextL2 = l2.next if l2 else null
nextNode = helper(nextL1, nextL2, newCarry)
return ListNode(digit, nextNode)
add_two_numbers_recursive.py
from typing import Optional, Tuple
class ListNode:
def __init__(self, val: int = 0, next: Optional['ListNode'] = None):
self.val = val
self.next = next
def addTwoNumbers(l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
"""
Add two numbers represented by linked lists in reverse order using recursion.
Time Complexity: O(max(m, n)) where m and n are the lengths of the lists
Space Complexity: O(max(m, n)) for the recursion call stack and output list
"""
def helper(l1: Optional[ListNode], l2: Optional[ListNode], carry: int) -> Optional[ListNode]:
# Base case: both lists are empty and no carry
if not l1 and not l2 and carry == 0:
return None
val1 = l1.val if l1 else 0
val2 = l2.val if l2 else 0
total = val1 + val2 + carry
digit = total % 10
new_carry = total // 10
# Move to next nodes
next_l1 = l1.next if l1 else None
next_l2 = l2.next if l2 else None
# Recursively build the rest of the list
next_node = helper(next_l1, next_l2, new_carry)
# Create node with current digit
return ListNode(digit, next_node)
return helper(l1, l2, 0)
# Test cases
if __name__ == "__main__":
# Helper function to create linked list from list
def create_linked_list(arr):
if not arr:
return None
head = ListNode(arr[0])
current = head
for val in arr[1:]:
current.next = ListNode(val)
current = current.next
return head
# Helper function to convert linked list to list for printing
def linked_list_to_list(head):
result = []
current = head
while current:
result.append(current.val)
current = current.next
return result
# Test case 1: [2,4,3] + [5,6,4] = [7,0,8] (342 + 465 = 807)
l1 = create_linked_list([2, 4, 3])
l2 = create_linked_list([5, 6, 4])
result = addTwoNumbers(l1, l2)
print(f"Test 1: {linked_list_to_list(result)}") # [7, 0, 8]
# Test case 2: [0] + [0] = [0]
l1 = create_linked_list([0])
l2 = create_linked_list([0])
result = addTwoNumbers(l1, l2)
print(f"Test 2: {linked_list_to_list(result)}") # [0]
# Test case 3: [9,9,9,9,9,9,9] + [9,9,9,9] = [8,9,9,9,0,0,0,1] (9999999 + 9999 = 10009998)
l1 = create_linked_list([9, 9, 9, 9, 9, 9, 9])
l2 = create_linked_list([9, 9, 9, 9])
result = addTwoNumbers(l1, l2)
print(f"Test 3: {linked_list_to_list(result)}") # [8, 9, 9, 9, 0, 0, 0, 1]
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
add_two_numbers_space_optimized.py
"""
Solution for Add Two Numbers
"""
def solve():
"""Implementation for approach 3 of Add Two Numbers"""
pass
if __name__ == "__main__":
print("Solution ready")