Imagine you have two large numbers written on paper, but instead of storing them as regular integers, each digit is stored in a separate box (node) of a linked list. The twist? The most significant digit comes first - just like how we normally write numbers!
You're given two non-empty linked lists representing two non-negative integers. Each node contains a single digit (0-9), and you need to add these two numbers together and return the sum as a new linked list.
For example:
Number 1: 7 → 2 → 4 → 3 represents 7243
Number 2: 5 → 6 → 4 represents 564
Sum: 7 → 8 → 0 → 7 represents 7807
The challenge is that we can't simply reverse the lists (like in Add Two Numbers I) because we need to maintain the original structure. We need to handle carries that propagate from right to left, just like elementary school addition!
Input & Output
example_1.py — Basic Addition
$Input:l1 = [7,2,4,3], l2 = [5,6,4]
›Output:[7,8,0,7]
💡 Note:7243 + 564 = 7807. The digits are stored with most significant digit first.
example_2.py — Addition with Carry
$Input:l1 = [2,4,3], l2 = [5,6,4]
›Output:[8,0,7]
💡 Note:243 + 564 = 807. Notice how the carry propagates from right to left.
example_3.py — Single Digits
$Input:l1 = [0], l2 = [0]
›Output:[0]
💡 Note:0 + 0 = 0. Edge case with single zero digits.
Constraints
The number of nodes in each linked list is in the range [1, 100]
0 ≤ Node.val ≤ 9
The input represents a valid number without leading zeros
Follow up: Could you solve it without reversing the input lists?
The optimal approach uses stacks to reverse the digit order naturally. Push all digits from both linked lists onto stacks, then pop and add them while handling carry propagation properly. This avoids integer overflow issues and demonstrates proper linked list manipulation with O(max(n,m)) time complexity.
Common Approaches
✓
Two Pointers
⏱️ Time: N/A
Space: N/A
Stack-Based Addition (Optimal)
⏱️ Time: O(max(n, m))
Space: O(n + m)
Since we need to add from right to left but the lists start from left, we can use stacks to reverse the order. Push all digits onto stacks, then pop and add them while handling carries properly.
Algorithm Steps — Algorithm Steps
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct PolyNode {
int coefficient;
int power;
struct PolyNode* next;
};
struct PolyNode* createNode(int coeff, int power) {
struct PolyNode* node = malloc(sizeof(struct PolyNode));
node->coefficient = coeff;
node->power = power;
node->next = NULL;
return node;
}
int parsePolynomial(char* input, int*** poly) {
if (strcmp(input, "[]") == 0) {
*poly = NULL;
return 0;
}
int count = 0;
char* temp = strdup(input);
char* ptr = temp;
// Count terms
while (*ptr) {
if (*ptr == '[') count++;
ptr++;
}
*poly = malloc(count * sizeof(int*));
int index = 0;
ptr = temp + 1; // Skip first '['
while (index < count) {
// Find next term
char* start = strchr(ptr, '[');
if (!start) break;
char* end = strchr(start, ']');
if (!end) break;
// Extract coefficient and power
char term[100];
strncpy(term, start + 1, end - start - 1);
term[end - start - 1] = '\0';
char* comma = strchr(term, ',');
*comma = '\0';
(*poly)[index] = malloc(2 * sizeof(int));
(*poly)[index][0] = atoi(term);
(*poly)[index][1] = atoi(comma + 1);
index++;
ptr = end + 1;
}
free(temp);
return count;
}
int** solution(int** poly1, int poly1Size, int** poly2, int poly2Size, int* returnSize) {
int maxSize = poly1Size + poly2Size;
int** result = malloc(maxSize * sizeof(int*));
int count = 0;
int i = 0, j = 0;
while (i < poly1Size && j < poly2Size) {
if (poly1[i][1] > poly2[j][1]) {
result[count] = malloc(2 * sizeof(int));
result[count][0] = poly1[i][0];
result[count][1] = poly1[i][1];
i++;
} else if (poly1[i][1] < poly2[j][1]) {
result[count] = malloc(2 * sizeof(int));
result[count][0] = poly2[j][0];
result[count][1] = poly2[j][1];
j++;
} else {
int coeffSum = poly1[i][0] + poly2[j][0];
if (coeffSum != 0) {
result[count] = malloc(2 * sizeof(int));
result[count][0] = coeffSum;
result[count][1] = poly1[i][1];
count++;
}
i++;
j++;
continue;
}
count++;
}
while (i < poly1Size) {
result[count] = malloc(2 * sizeof(int));
result[count][0] = poly1[i][0];
result[count][1] = poly1[i][1];
i++;
count++;
}
while (j < poly2Size) {
result[count] = malloc(2 * sizeof(int));
result[count][0] = poly2[j][0];
result[count][1] = poly2[j][1];
j++;
count++;
}
*returnSize = count;
return result;
}
int main() {
char line1[10000], line2[10000];
fgets(line1, sizeof(line1), stdin);
fgets(line2, sizeof(line2), stdin);
// Remove newlines
line1[strcspn(line1, "\n")] = 0;
line2[strcspn(line2, "\n")] = 0;
int** poly1;
int** poly2;
int poly1Size = parsePolynomial(line1, &poly1);
int poly2Size = parsePolynomial(line2, &poly2);
int returnSize;
int** result = solution(poly1, poly1Size, poly2, poly2Size, &returnSize);
printf("[");
for (int i = 0; i < returnSize; i++) {
if (i > 0) printf(",");
printf("[%d,%d]", result[i][0], result[i][1]);
}
printf("]\n");
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
n
2n
✓ Linear Growth
Space Complexity
n
2n
⚡ Linearithmic Space
68.0K Views
HighFrequency
~18 minAvg. Time
1.5K Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.