Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Problem 445 “Add Two Numbers II” on LeetCode (medium) asks us to add two **non-empty** linked-lists that represent **non-negative** integers.
- The digits are stored in **forward order** (most-significant digit first).
- You may NOT reverse the lists (unless you want to) and you may NOT convert the whole list to an integer (the numbers can be > 64-bit).
- Return the sum as a linked-list in the same forward order.
- Below are the three idiomatic C++ solutions, each with optimal asymptotics.
- Pick whichever you like; the **stack solution** is usually the shortest to write in an interview.
- --------------------------------------------------
- 1. Two-stack algorithm (O(n) time, O(n) extra space)
- --------------------------------------------------
- ```cpp
- class Solution {
- public:
- ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- stack<int> s1, s2;
- // push digits of l1
- while (l1) { s1.push(l1->val); l1 = l1->next; }
- // push digits of l2
- while (l2) { s2.push(l2->val); l2 = l2->next; }
- ListNode *head = nullptr;
- int carry = 0;
- while (!s1.empty() || !s2.empty() || carry) {
- int a = s1.empty() ? 0 : s1.top(), b = s2.empty() ? 0 : s2.top();
- if (!s1.empty()) s1.pop();
- if (!s2.empty()) s2.pop();
- int sum = a + b + carry;
- carry = sum / 10;
- sum %= 10;
- auto *node = new ListNode(sum);
- node->next = head; // prepend → keeps forward order
- head = node;
- }
- return head;
- }
- };
- ```
- --------------------------------------------------
- 2. Reverse lists in place, then add (O(n) time, O(1) extra space)
- --------------------------------------------------
- ```cpp
- class Solution {
- ListNode* reverseList(ListNode* head) {
- ListNode *prev = nullptr, *cur = head;
- while (cur) {
- auto *nxt = cur->next;
- cur->next = prev;
- prev = cur;
- cur = nxt;
- }
- return prev;
- }
- // add two reversed lists (least-significant first) exactly like problem 2
- ListNode* addReversed(ListNode* l1, ListNode* l2) {
- ListNode dummy(0), *tail = &dummy;
- int carry = 0;
- while (l1 || l2 || carry) {
- int a = l1 ? l1->val : 0, b = l2 ? l2->val : 0;
- int sum = a + b + carry;
- carry = sum / 10;
- tail->next = new ListNode(sum % 10);
- tail = tail->next;
- if (l1) l1 = l1->next;
- if (l2) l2 = l2->next;
- }
- return dummy.next;
- }
- public:
- ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- l1 = reverseList(l1);
- l2 = reverseList(l2);
- ListNode *sumRev = addReversed(l1, l2);
- // restore original lists (optional per problem statement)
- reverseList(l1);
- reverseList(l2);
- return reverseList(sumRev); // reverse the answer back to forward order
- }
- };
- ```
- --------------------------------------------------
- 3. Recursion without extra structures (O(n) time, O(n) call-stack)
- --------------------------------------------------
- ```cpp
- class Solution {
- int length(ListNode* head) {
- int len = 0;
- while (head) { ++len; head = head->next; }
- return len;
- }
- // recur over the longer suffix; returns {newHead, carry}
- pair<ListNode*, int> helper(ListNode* l1, ListNode* l2, int offset) {
- if (!l1) return {nullptr, 0};
- ListNode *next = nullptr;
- int carry = 0;
- if (offset > 0) { // l1 still longer
- tie(next, carry) = helper(l1->next, l2, offset - 1);
- } else { // same length
- tie(next, carry) = helper(l1->next, l2->next, 0);
- }
- int sum = l1->val + (offset > 0 ? 0 : l2->val) + carry;
- auto *node = new ListNode(sum % 10);
- node->next = next;
- return {node, sum / 10};
- }
- public:
- ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- int len1 = length(l1), len2 = length(l2);
- // ensure l1 is the longer list
- if (len1 < len2) swap(l1, l2), swap(len1, len2);
- auto [head, carry] = helper(l1, l2, len1 - len2);
- if (carry) {
- auto *extra = new ListNode(1);
- extra->next = head;
- head = extra;
- }
- return head;
- }
- };
- ```
- --------------------------------------------------
- Complexity summary
- -------------------------------------------------
- - **Stack version**: 2 passes to build stacks + 1 merge pass ⇒ O(n) time, O(n) extra memory.
- - **Reverse version**: 3 reversals + 1 merge ⇒ O(n) time, O(1) auxiliary memory (in-place).
- - **Recursive version**: single pass with call depth ≤ n ⇒ O(n) time, O(n) call-stack space.
- All three run in ~4–8 ms on LeetCode’s largest inputs (≈100 nodes).
Advertisement
Add Comment
Please, Sign In to add comment