Add Two Numbers Represented as Linked List in DSA C - Time & Space Complexity
We want to know how the time to add two numbers stored as linked lists grows as the numbers get longer.
How does the number of steps change when the linked lists have more digits?
Analyze the time complexity of the following code snippet.
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
struct ListNode* current = dummy;
int carry = 0;
while (l1 || l2 || carry) {
int sum = carry;
if (l1) { sum += l1->val; l1 = l1->next; }
if (l2) { sum += l2->val; l2 = l2->next; }
carry = sum / 10;
current->next = malloc(sizeof(struct ListNode));
current = current->next;
current->val = sum % 10;
current->next = NULL;
}
return dummy->next;
}
This code adds two numbers digit by digit, moving through each linked list once.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves 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.
Each step processes one digit from the input lists, so the total steps grow directly with the number of digits.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The number of steps grows in a straight line as the input size increases.
Time Complexity: O(n)
This means the time to add the numbers grows directly with the number of digits in the longer list.
[X] Wrong: "The time depends on the sum of the numbers, not the length of the lists."
[OK] Correct: The code processes each digit once, so the time depends on how many digits there are, not the actual number values.
Understanding this helps you explain how linked list traversal affects performance, a key skill in many coding problems.
"What if the input lists were doubly linked lists? How would the time complexity change?"
Practice
Each node contains a single digit and digits are stored in reverse order. What is the goal?Solution
Step 1: Understand the representation of numbers in linked lists
Each linked list node holds one digit, and the digits are stored in reverse order, meaning the first node is the ones place.Step 2: Define the goal of the problem
The goal is to add these two numbers digit by digit, handling any carry, and return the result as a new linked list in the same reverse order format.Final Answer:
Add the two numbers digit by digit and return the sum as a linked list in reverse order. -> Option CQuick Check:
Adding reversed digit lists = sum list reversed [OK]
- Trying to add numbers as integers directly
- Ignoring carry between digits
- Not returning the result in reverse order
Solution
Step 1: Understand C struct syntax for linked list nodes
In C, to define a node with an integer value and pointer to next node, use 'struct Node* next;'.Step 2: Identify correct pointer usage
struct Node { int val; struct Node* next; }; correctly uses 'struct Node* next;' which is the pointer to the next node. struct Node { int val; Node* next; }; misses 'struct' keyword, C uses struct Node instead of pointer, D uses 'prev' which is for doubly linked list.Final Answer:
struct Node { int val; struct Node* next; }; -> Option DQuick Check:
Pointer to next node = struct Node* next [OK]
- Omitting 'struct' keyword before Node*
- Using struct Node instead of pointer for next
- Confusing singly linked list with doubly linked list
List1: 2 -> 4 -> 3 -> null (represents 342)
List2: 5 -> 6 -> 4 -> null (represents 465)
Code snippet adds digits with carry:
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
Digits are 7 (ones), 0 (tens), 8 (hundreds), so linked list is 7 -> 0 -> 8 -> null.Final Answer:
7 -> 0 -> 8 -> null -> Option AQuick Check:
342 + 465 = 807 reversed = 7->0->8 [OK]
- Not handling carry correctly
- Adding digits without carry from previous sum
- Confusing order of digits in output
while(l1 != NULL || l2 != NULL) {
int sum = carry;
if(l1 != NULL) { sum += l1->val; l1 = l1->next; }
if(l2 != NULL) { sum += l2->val; l2 = l2->next; }
carry = sum / 10;
sum = sum % 10;
newNode->val = sum;
newNode = newNode->next;
}Solution
Step 1: Analyze pointer usage for newNode
The code assigns newNode->val but then moves newNode to newNode->next without initializing newNode->next, so newNode->next is likely NULL or garbage.Step 2: Identify missing node creation
Before moving newNode = newNode->next, a new node must be created and linked to newNode->next to avoid undefined behavior.Final Answer:
newNode->next is not initialized before assignment, causing undefined behavior. -> Option AQuick Check:
Always create new node before moving pointer [OK]
- Not creating new nodes for the result list
- Incorrect loop condition causing missed nodes
- Incorrect carry update logic
List1: 9 -> 9 -> 9 -> 9 -> null (represents 9999)
List2: 1 -> null (represents 1)
What is the correct resulting linked list after adding these two numbers?
Solution
Step 1: Add digits with carry step-by-step
9+1=10 (digit 0, carry 1), next 9+0+1=10 (digit 0, carry 1), repeat for next two 9s similarly.Step 2: Handle final carry
After last digit, carry is 1, so add new node with value 1 at the end.Final Answer:
0 -> 0 -> 0 -> 0 -> 1 -> null -> Option BQuick Check:
9999 + 1 = 10000 reversed = 0->0->0->0->1 [OK]
- Forgetting to add final carry node
- Stopping addition early when one list ends
- Misplacing the carry digit in the result
Ready to prove it?
Pass the test and this pattern moves unknown
