Add Two Numbers Represented as Linked List in DSA Javascript - Time & Space Complexity
We want to understand how the time needed to add two numbers stored as linked lists grows as the numbers get longer.
How does the work change when the linked lists have more digits?
Analyze the time complexity of the following code snippet.
function addTwoNumbers(l1, l2) {
let dummy = new ListNode(0);
let current = dummy;
let carry = 0;
while (l1 || l2 || carry) {
let sum = (l1 ? l1.val : 0) + (l2 ? l2.val : 0) + carry;
carry = Math.floor(sum / 10);
current.next = new ListNode(sum % 10);
current = current.next;
if (l1) l1 = l1.next;
if (l2) l2 = l2.next;
}
return dummy.next;
}
This code adds two numbers digit by digit, stored in linked lists, and returns the sum as a new linked list.
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, plus one extra if there is a carry at the end.
As the number of digits (nodes) increases, the loop runs more times, roughly once per digit.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 loop cycles |
| 100 | About 100 loop cycles |
| 1000 | About 1000 loop cycles |
Pattern observation: The number of steps grows directly with the number of digits.
Time Complexity: O(n)
This means the time to add the numbers grows linearly with the length of the longer linked list.
[X] Wrong: "The time depends on both lists multiplied together, like O(n*m)."
[OK] Correct: The code only walks through each list once, so the time depends on the longer list length, not the product of lengths.
Understanding this linear time complexity helps you explain how to efficiently process linked lists digit by digit, a common pattern in coding problems.
"What if the digits were stored in forward order instead of reverse? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem statement
The problem requires adding two numbers where each number is represented by a linked list. Each node contains a single digit, and digits are stored in reverse order.Step 2: Identify the expected output
The output should be a linked list representing the sum of the two numbers, also in reverse order.Final Answer:
Add two numbers represented as linked lists and return their sum as a linked list -> Option AQuick Check:
Adding digits node by node = Add linked lists [OK]
- Thinking digits are stored in normal order
- Confusing addition with multiplication
- Returning a number instead of a linked list
Solution
Step 1: Check the standard node structure
The node should have a property named 'val' for the digit and 'next' for the next node pointer.Step 2: Verify the syntax correctness
function ListNode(val) { this.val = val; this.next = null; } correctly defines a function constructor with 'val' and 'next' properties initialized properly.Final Answer:
function ListNode(val) { this.val = val; this.next = null; } -> Option AQuick Check:
Node with val and next properties = function ListNode(val) { this.val = val; this.next = null; } [OK]
- Using 'value' instead of 'val'
- Using 'nextNode' instead of 'next'
- Incorrect constructor syntax
function addTwoNumbers(l1, l2) {
let dummy = new ListNode(0);
let current = dummy;
let carry = 0;
while (l1 || l2 || carry) {
let sum = carry;
if (l1) { sum += l1.val; l1 = l1.next; }
if (l2) { sum += l2.val; l2 = l2.next; }
carry = Math.floor(sum / 10);
current.next = new ListNode(sum % 10);
current = current.next;
}
return dummy.next;
}Solution
Step 1: Add digits node by node with carry
2+5=7 (carry 0), 4+6=10 (carry 1), 3+4+1=8 (carry 0)Step 2: Form the resulting linked list
The digits are 7 -> 0 -> 8 representing 807 in reverse order.Final Answer:
7 -> 0 -> 8 -> null -> Option BQuick Check:
342 + 465 = 807 = 7->0->8 [OK]
- Ignoring carry after adding digits
- Mixing digit order in output
- Returning sum as a number, not linked list
function addTwoNumbers(l1, l2) {
let dummy = new ListNode(0);
let current = dummy;
let carry = 0;
while (l1 !== null && l2 !== null) {
let sum = carry + l1.val + l2.val;
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 loop condition
The loop stops when either l1 or l2 becomes null, missing remaining nodes if lists differ in length.Step 2: Correct the loop condition
Using '||' ensures the loop continues until both lists and carry are fully processed.Final Answer:
The loop condition should use '||' instead of '&&' to handle lists of different lengths. -> Option DQuick Check:
Loop condition must cover all nodes = The loop condition should use '||' instead of '&&' to handle lists of different lengths. [OK]
- Stopping loop too early with '&&'
- Ignoring leftover carry after loop
- Not advancing pointers correctly
function addTwoNumbers(l1, l2) {
let dummy = new ListNode(0);
let current = dummy;
let carry = 0;
while (l1 || l2 || carry) {
let sum = carry;
if (l1) { sum += l1.val; l1 = l1.next; }
if (l2) { sum += l2.val; l2 = l2.next; }
carry = Math.floor(sum / 10);
current.next = new ListNode(sum % 10);
current = current.next;
}
return dummy.next;
}Solution
Step 1: Understand the need to handle different lengths and carry
When lists differ in length, addition must continue until both lists and carry are fully processed.Step 2: Use a loop condition that checks l1, l2, or carry
This ensures the loop adds all digits and creates a new node if carry remains after lists end.Final Answer:
Use a loop condition that continues while l1, l2, or carry exists, adding carry as a new node if needed. -> Option CQuick Check:
Loop until all digits and carry processed = Use a loop condition that continues while l1, l2, or carry exists, adding carry as a new node if needed. [OK]
- Ignoring carry after lists end
- Trying to pad shorter list manually
- Appending leftover nodes without adding carry
Ready to prove it?
Pass the test and this pattern moves unknown
