31. Add Two Numbers
mediumAsked at DatadogAdd two non-negative integers represented as reversed-order linked lists. Datadog uses this to test carry-propagation logic — the same logic as their atomic-counter rollup across pipeline stages.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Datadog loops.
- Glassdoor (2026-Q1)— Datadog phone screen linked-list arithmetic.
- Blind (2025-11)— Recurring at Datadog NYC.
Problem
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.
Constraints
The number of nodes in each linked list is in the range [1, 100].0 <= Node.val <= 9It is guaranteed that the list represents a number that does not have leading zeros.
Examples
Example 1
l1 = [2,4,3], l2 = [5,6,4][7,0,8]Explanation: 342 + 465 = 807.
Example 2
l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9][8,9,9,9,0,0,0,1]Approaches
1. Convert to BigInt, add, rebuild
Decode both lists to BigInts, add, encode back.
- Time
- O(n+m)
- Space
- O(n+m)
function addTwoNumbers(l1, l2) {
function toNum(l) { let n = 0n, p = 1n; while (l) { n += BigInt(l.val) * p; p *= 10n; l = l.next; } return n; }
let sum = toNum(l1) + toNum(l2);
const dummy = { val: 0, next: null };
let tail = dummy;
if (sum === 0n) return { val: 0, next: null };
while (sum > 0n) { tail.next = { val: Number(sum % 10n), next: null }; tail = tail.next; sum /= 10n; }
return dummy.next;
}Tradeoff: Works but signals you avoid the digit-by-digit logic. Interviewers see this as a dodge.
2. Digit-by-digit with carry (optimal)
Walk both lists in lockstep; sum digits + carry; emit (sum % 10), propagate carry. Handle uneven lengths and trailing carry.
- Time
- O(max(n, m))
- Space
- O(max(n, m)) output
function addTwoNumbers(l1, l2) {
const dummy = { val: 0, next: null };
let tail = dummy;
let carry = 0;
while (l1 || l2 || carry) {
const a = l1 ? l1.val : 0;
const b = l2 ? l2.val : 0;
const sum = a + b + carry;
tail.next = { val: sum % 10, next: null };
tail = tail.next;
carry = Math.floor(sum / 10);
if (l1) l1 = l1.next;
if (l2) l2 = l2.next;
}
return dummy.next;
}Tradeoff: Single pass; handles uneven lengths and final carry. Direct carry-propagation pattern Datadog uses in their counter rollup.
Datadog-specific tips
Datadog interviewers grade on the three loop conditions: l1 OR l2 OR carry. Forgetting any one bombs an edge case. They'll follow up with: 'Now do it with digits stored MSB-first' — that's LC 445, requiring stacks or reversal.
Common mistakes
- Loop condition while (l1 && l2) — misses uneven-length lists.
- Loop condition while (l1 || l2) — misses trailing carry like [9,9] + [1] = [0,0,1].
- Forgetting to advance l1/l2 only when they're non-null — crash on null deref.
Follow-up questions
An interviewer at Datadog may pivot to one of these next:
- Add Two Numbers II (LC 445) — digits stored MSB-first.
- Plus One Linked List (LC 369) — increment by 1.
- Add Strings (LC 415) — same pattern on strings.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
What about the trailing carry?
If both lists end and carry is 1, you need one more node. That's why the loop condition is l1 || l2 || carry, not just l1 || l2.
Why reverse-order digits?
Carry propagates from least-significant to most-significant. Reverse order means the head IS the least-significant digit, so you can walk forward and propagate carry naturally.
Practice these live with InterviewChamp.AI
Drill Add Two Numbers and other Datadog interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →