Linked List · 10 of 36
Add two numbers represented by linked lists
Two numbers are written one digit per box, biggest digit first, and you add them the way you add on paper, carrying when a column passes 9.
- Simple way
- time O(m + n)
room O(m + n) - Clever way
- time O(m + n)
room O(1)
The problem, simply
You get two linked lists. Each one is a number, one digit per box, with the biggest digit at the head. So 9 -> 9 -> 6 is 996 and 2 -> 7 is 27.
Build a new list that holds their sum, also biggest digit first. For 996 + 27 the answer is 1 -> 0 -> 2 -> 3. The numbers can be hundreds of digits long, far too big for an int or a long.
A story to remember it
Picture it
Two chains, big digit first. 996 has three boxes, 27 has two. The ones digits, 6 and 7, are at the far ends, where the arrows run out.
- checking
Examples
A normal case
- In
a = 4 -> 5, b = 3 -> 4 -> 5- Out
3 -> 9 -> 0
45 + 345 = 390. The lists have different lengths, and the ones digits line up on the right.
Carries all the way
- In
a = 9 -> 9 -> 6, b = 2 -> 7- Out
1 -> 0 -> 2 -> 3
996 + 27 = 1023. The carry runs off the left end, so the answer is longer than both inputs.
Zeros
- In
a = 0, b = 0- Out
0
0 + 0 is 0. The answer is one box with 0, not an empty list.
Leading zeros in the input
- In
a = 0 -> 0 -> 7, b = 5- Out
1 -> 2
007 + 5 = 12. The answer should not start with extra zeros, so strip them at the end (keep one box if the sum is 0).
Way 1: the simple way
The first idea, turning each list into a long and adding, breaks for long numbers: a long holds only about 19 digits. So do it digit by digit, and use two stacks of plates to read the digits from the right.
- Walk list
aand push each digit onto stack 1. Do the same forband stack 2. The ones digits end up on top. - While a stack has plates or the carry is not 0: pop the top of each stack, add them and the carry.
- Make a box with
sum % 10and put it in front of the answer. The new carry issum / 10.
Both lists poured into stacks. The ones digits, 6 and 7, are on top, so they come off first.
- looking now
class Solution {
public ListNode addTwoLists(ListNode a, ListNode b) {
Deque<Integer> s1 = new ArrayDeque<>(), s2 = new ArrayDeque<>();
for (ListNode p = a; p != null; p = p.next) s1.push(p.val);
for (ListNode p = b; p != null; p = p.next) s2.push(p.val);
ListNode ans = null;
int carry = 0;
while (!s1.isEmpty() || !s2.isEmpty() || carry > 0) {
int sum = carry;
if (!s1.isEmpty()) sum += s1.pop(); // ones digit comes off first
if (!s2.isEmpty()) sum += s2.pop();
ListNode box = new ListNode(sum % 10);
box.next = ans; // put the new digit in front
ans = box;
carry = sum / 10;
}
while (ans != null && ans.next != null && ans.val == 0) ans = ans.next; // no leading zeros
return ans;
}
}How long it takes: every digit is pushed once and popped once, O(m + n). Extra room: two stacks as long as the lists, O(m + n), on top of the answer list.
Way 2: the clever way
The stacks were only there to read from the right. We can get the same thing for free by flipping each chain with the three finger reversal.
- Reverse
aand reverseb. Now both start at the ones digit. - Walk both together with a carry. Missing digits count as 0.
- For each column, make a box with
sum % 10and put it in front of the answer, so the answer comes out biggest digit first with no third reversal. - Strip leading zeros. If the caller still needs the inputs, flip them back.
Flip, add from the small end, put each new digit in front
01 / 08
Two numbers: 996 and 27. Their arrows run from the big digit to the small digit, but adding starts at the small digit.
- looking now
- done
- answer
- just added
class Solution {
public ListNode addTwoLists(ListNode a, ListNode b) {
ListNode ra = reverse(a), rb = reverse(b); // ones digit first
ListNode p = ra, q = rb, ans = null;
int carry = 0;
while (p != null || q != null || carry > 0) {
int sum = carry;
if (p != null) { sum += p.val; p = p.next; }
if (q != null) { sum += q.val; q = q.next; }
ListNode box = new ListNode(sum % 10);
box.next = ans; // new digit goes in front
ans = box;
carry = sum / 10;
}
reverse(ra); // give the caller their lists back
reverse(rb);
while (ans != null && ans.next != null && ans.val == 0) ans = ans.next;
return ans;
}
private ListNode reverse(ListNode head) {
ListNode prev = null, curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}How long it takes: each list is flipped twice and walked once, O(m + n). Extra room: only a few fingers, O(1), apart from the answer list that we must return anyway.
Watch out for
- Converting to
intorlongoverflows once the numbers pass about 19 digits. Never do it in an interview. - Lining up the wrong ends. The ones digits are at the tails, so lists of different lengths must be matched from the right, not from the head.
- Leading zeros. Strip them, but keep one box when the sum is 0.
- Forgetting that reversing changes the caller's lists. Flip them back, or say clearly that you modify the input.
What interviewers ask next
- What if the digits are stored ones digit first (LeetCode 2)? Then no flipping is needed: walk both heads together with a carry and append to a tail with a dummy head.
- Can you do it without changing the inputs and without stacks? Yes, with recursion: pad the shorter list with zeros in front, recurse to the end, and return the carry on the way back. That costs
O(m + n)call stack. - Subtract the two numbers instead? Same shape: flip, subtract column by column with a borrow, then strip leading zeros. First compare lengths to know which number is bigger.
- Multiply them? See the multiply problem: do it like school multiplication, or work modulo a big prime if only the remainder is asked.
Remember this
Grown-up words: the boxes are nodes, the column overflow is the carry, the stacks of plates are a stack (LIFO), flipping is in place list reversal, and putting a box in front is inserting at the head.