Linked List · 32 of 36
Multiply 2 no. represented by LL
Two huge numbers are written one digit per box, and you must give back their product cut down to a fixed size by a remainder, without ever holding the giant numbers.
- Simple way
- time O(n m)
room O(n + m) - Clever way
- time O(n + m)
room O(1)
The problem, simply
You get two linked lists. Each is a number, one digit per box, biggest digit first. So 9 -> 4 -> 6 is 946 and 8 -> 4 is 84.
Return the product of the two numbers. The lists can be hundreds of digits long, so the product can be far too big for a long. That is why the GeeksforGeeks version asks for the product modulo 1000000007: the remainder after dividing by 1000000007 (a big prime, written 10^9 + 7).
A story to remember it
Picture it
946 and 84 as linked lists, biggest digit first. Their product is 79464, which is smaller than 1000000007, so the answer is 79464.
Examples
A small case
- In
a = 3 -> 2, b = 2- Out
64
32 times 2 is 64. No wrapping needed.
A normal case
- In
a = 9 -> 4 -> 6, b = 8 -> 4- Out
79464
946 times 84 is 79464.
A huge case
- In
a and b are both twelve 9s- Out
49014001
999999999999 squared does not fit in a long. Wrapping each number while reading, then wrapping the product, gives 49014001.
A zero
- In
a = 0, b = 9 -> 9- Out
0
Anything times zero is zero.
Way 1: the simple way
The first idea, building each number in a long and multiplying, breaks fast: a long holds about 19 digits, and even the product of two 10 digit numbers overflows. So do it the school way, digit by digit, and only wrap at the end.
- Copy each list's digits into an array, ones digit first.
- For every digit
iofaand every digitjofb, adda[i] * b[j]into sloti + jof a result array. - Sweep the slots from the ones place up and pass carries along, so every slot holds one digit.
- Read the exact product from the biggest digit down, wrapping by
1000000007as you go.
946 times 84 in slots, ones place on the left. Slot 1 gets 4 times 4 plus 6 times 8, which is 64. After carrying, the slots read 4 6 4 9 7, which is 79464 backwards.
- looking now
- done
class Solution {
static final long MOD = 1_000_000_007L;
public long multiplyTwoLists(Node first, Node second) {
List<Integer> a = digits(first), b = digits(second); // ones digit first
int[] slot = new int[a.size() + b.size()];
for (int i = 0; i < a.size(); i++)
for (int j = 0; j < b.size(); j++)
slot[i + j] += a.get(i) * b.get(j); // school multiplication
int carry = 0;
for (int k = 0; k < slot.length; k++) {
int v = slot[k] + carry;
slot[k] = v % 10;
carry = v / 10;
}
long ans = 0;
for (int k = slot.length - 1; k >= 0; k--) ans = (ans * 10 + slot[k]) % MOD;
return ans;
}
private List<Integer> digits(Node head) {
List<Integer> d = new ArrayList<>();
for (Node p = head; p != null; p = p.next) d.add(p.data);
Collections.reverse(d);
return d;
}
}How long it takes: every digit of a meets every digit of b, O(n m). Extra room: the digit arrays and slots, O(n + m). This is the right tool if the interviewer wants the exact product as a list, but it does far too much work when only the remainder is asked.
Way 2: the clever way
Use the clock. Reading a number left to right is "times 10, plus the next digit". We may wrap after every step, so the running number always stays below 1000000007.
- Walk list
a:x = (x * 10 + digit) % MOD. - Walk list
bthe same way to gety. - Return
(x * y) % MOD. Both are below about10^9, so their product is below about10^18, which fits in along.
Read each number digit by digit, wrapping as you go
01 / 07
Start reading a. The running number x is 0.
- x
- 0
- looking now
- done
- answer
With twelve 9s, the wrapping finally matters. After nine digits x is 999999999. The tenth digit would make 9999999999, which wraps to 999999936, and it stays small from then on:
Reading twelve 9s. After the tenth box, x wraps around the giant clock and stays below 1000000007.
- x before
- 999999999
- x after
- 999999936
- looking now
- done
class Solution {
static final long MOD = 1_000_000_007L;
public long multiplyTwoLists(Node first, Node second) {
long x = 0, y = 0;
for (Node p = first; p != null; p = p.next) x = (x * 10 + p.data) % MOD; // wrap every digit
for (Node q = second; q != null; q = q.next) y = (y * 10 + q.data) % MOD;
return (x * y) % MOD; // fits in a long
}
}How long it takes: one walk over each list, O(n + m). Extra room: two numbers, O(1).
Watch out for
- Using
intforxandy. Two numbers near10^9multiply to about10^18, which needs along. - Multiplying three wrapped numbers at once, like
x * y * z. That can reach10^27and overflow. Wrap after each multiplication. - Leading zeros in a list, like
0 -> 0 -> 7. They are harmless here: they just keepxat 0 until the 7. - Reading the digits in the wrong order. The head is the biggest digit, so "times 10 plus digit" walking from the head is right.
What interviewers ask next
- Return the full product as a linked list, no modulo. Use the school way from Way 1 and build the answer list from the slots, skipping leading zeros.
O(n m). - Can you multiply huge numbers faster than
O(n m)? Karatsuba splits each number in halves and needs only three half size products instead of four, aboutO(n^1.58). Fast Fourier transform methods go to aboutO(n log n). - Why is wrapping allowed? Because
(a times b) mod Mequals((a mod M) times (b mod M)) mod M, and the same for adding. Remainders only care about remainders. - Why
10^9 + 7? It is prime, it fits in anint, and the product of two such remainders still fits in along. - Add the two numbers modulo
Minstead. Same reading, then(x + y) % MOD.
Remember this
Grown-up words: the giant clock is modular arithmetic, 1000000007 is the modulus, wrapping is taking the remainder with %, reading digit by digit is Horner's method, and the school way is grade school long multiplication.