Add Two Numbers Represented as Linked List in DSA Typescript - Time & Space Complexity
We want to understand how the time needed to add two numbers changes as the numbers get longer.
How does the process scale when the linked lists grow in size?
Analyze the time complexity of the following code snippet.
function addTwoNumbers(l1: ListNode | null, l2: ListNode | null): ListNode | null {
let dummyHead = new ListNode(0);
let current = dummyHead;
let carry = 0;
while (l1 !== null || l2 !== null) {
let x = l1 ? l1.val : 0;
let y = l2 ? l2.val : 0;
let sum = carry + x + y;
carry = Math.floor(sum / 10);
current.next = new ListNode(sum % 10);
current = current.next;
if (l1) l1 = l1.next;
if (l2) l2 = l2.next;
}
if (carry > 0) {
current.next = new ListNode(carry);
}
return dummyHead.next;
}
This code adds two numbers stored as linked lists digit by digit, handling carry over.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that goes through each node of the linked lists.
- How many times: It runs once for each digit in the longer linked list.
As the number of digits (nodes) increases, the loop runs more times, directly proportional to the input size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 loop cycles |
| 100 | About 100 loop cycles |
| 1000 | About 1000 loop cycles |
Pattern observation: The time grows linearly with the number of digits.
Time Complexity: O(n)
This means the time to add the numbers grows directly with the length of the longer linked list.
[X] Wrong: "The time complexity is O(n²) because we add digits one by one and create new nodes each time."
[OK] Correct: Each digit is processed once in a single loop, so operations grow linearly, not quadratically.
Understanding this linear time complexity helps you explain how your solution scales and why it is efficient for adding large numbers represented as linked lists.
"What if the input lists were doubly linked lists instead of singly linked? How would the time complexity change?"
Practice
Solution
Step 1: Understand the input format
The numbers are given as linked lists where each node contains a single digit, and digits are stored in reverse order.Step 2: Understand the required output
You must add these two numbers digit by digit and return the sum as a linked list in the same reversed format.Final Answer:
Add two numbers digit-wise from linked lists and return sum as linked list -> Option BQuick Check:
Adding digits node by node = Add two numbers as linked lists [OK]
- Confusing input format as normal integers
- Returning sum as integer instead of linked list
- Ignoring carry over digits
Solution
Step 1: Check for correct TypeScript class syntax
class ListNode { val: number; next: ListNode | null; constructor(val?: number, next?: ListNode | null) { this.val = val ?? 0; this.next = next ?? null; } } defines a class with val as number and next as ListNode or null, with a constructor and default values.Step 2: Verify other options
interface ListNode { value: string; next: ListNode; } uses interface with string type and no null for next, type ListNode = { val: string; next: ListNode | undefined; }; uses string val and next possibly undefined, function ListNode(val) { this.val = val; this.next = null; } is JavaScript function style without types.Final Answer:
TypeScript class with number val and nullable next -> Option AQuick Check:
TypeScript class with number val and nullable next = class ListNode { val: number; next: ListNode | null; constructor(val?: number, next?: ListNode | null) { this.val = val ?? 0; this.next = next ?? null; } } [OK]
- Using string instead of number for val
- Not allowing next to be null
- Using JavaScript function instead of TypeScript class
Solution
Step 1: Add digits node by node with carry
2+5=7 (no carry), 4+6=10 (carry 1), 3+4+1=8 (no carry)Step 2: Form the resulting linked list
Digits are 7, 0 (from 10), and 8, so linked list is 7 -> 0 -> 8 -> nullFinal Answer:
7 -> 0 -> 8 -> null -> Option CQuick Check:
342 + 465 = 807 represented as 7->0->8 [OK]
- Not carrying over when sum >= 10
- Reversing the order of digits in output
- Adding digits incorrectly without carry
function addTwoNumbers(l1: ListNode | null, l2: ListNode | null): ListNode | null {
let dummy = new ListNode(0);
let current = dummy;
let carry = 0;
while (l1 !== null && l2 !== null) {
let sum = l1.val + l2.val + carry;
carry = Math.floor(sum / 10);
current.next = new ListNode(sum % 10);
current = current.next;
l1 = l1.next;
l2 = l2.next;
}
return dummy.next;
}Solution
Step 1: Analyze the while loop condition
The loop runs only while both l1 and l2 are not null, so it stops if one list is longer.Step 2: Identify missing handling of remaining nodes
After the loop, remaining nodes of the longer list and any carry are not processed, causing incorrect result.Final Answer:
Loop stops too early, missing remaining nodes in longer list -> Option DQuick Check:
Loop condition && misses longer list nodes [OK]
- Using && instead of || in loop condition
- Not processing leftover carry after loop
- Returning dummy instead of dummy.next
Solution
Step 1: Add digits with carry from right to left
9+1=10 (0 carry 1), next 9+0+1=10 (0 carry 1), repeat for next two 9s with carry 1.Step 2: Add final carry as new node
After last 9+0+1=10, carry 1 remains, so add new node with 1 at the end.Final Answer:
0 -> 0 -> 0 -> 0 -> 1 -> null -> Option AQuick Check:
9999 + 1 = 10000 as linked list 0->0->0->0->1 [OK]
- Not adding extra node for final carry
- Stopping addition early when one list ends
- Incorrectly placing carry node position
Ready to prove it?
Pass the test and this pattern moves unknown
