Searching & Sorting · 16 of 36
Product array Puzzle
For every kid in a line, multiply the numbers of everyone else, using what the kids to the left and to the right already worked out.
- Simple way
- time O(n^2)
room O(1) - Clever way
- time O(n)
room O(1)
The problem, simply
You get an array arr of n numbers. Build a new array prod where prod[i] is the product of all numbers in arr except arr[i].
You may not use division. That rule matters: with zeros in the array, "divide the total by arr[i]" breaks anyway.
A story to remember it
Picture it
For index 2 (the 5): the left part is 10 x 3 = 30, the right part is 6 x 2 = 12, so prod[2] = 30 x 12 = 360.
- looking now
- checking
- answer
- path
Examples
A normal case
- In
[10, 3, 5, 6, 2]- Out
[180, 600, 360, 300, 900]
For example prod[0] = 3 x 5 x 6 x 2 = 180.
One zero
- In
[1, 2, 0, 4]- Out
[0, 0, 8, 0]
Every product that includes the 0 is 0. Only the spot of the 0 itself gets 1 x 2 x 4 = 8.
Two zeros
- In
[0, 2, 0]- Out
[0, 0, 0]
Every spot still has at least one 0 among the others.
Negatives
- In
[-1, 2, -3]- Out
[-6, 3, -2]
Signs work out by themselves, since we only multiply.
One number
- In
[5]- Out
[1]
There is nobody else, and the product of nothing is 1.
Way 1: the simple way
For each position, multiply all the other numbers.
- For each
i, start withp = 1. - For each
jthat is noti, multiplypbyarr[j]. - Store
pinprod[i].
class Solution {
public long[] productExceptSelf(int[] arr) {
int n = arr.length;
long[] prod = new long[n];
for (int i = 0; i < n; i++) {
long p = 1;
for (int j = 0; j < n; j++) {
if (j != i) p *= arr[j]; // everyone but me
}
prod[i] = p;
}
return prod;
}
}How long it takes: n products of n - 1 numbers each, O(n^2). Extra room: only the answer array, O(1) extra.
Way 2: the clever way
prod[i] = (product of everything left of i) x (product of everything right of i). Both parts can be built in one walk each.
- Walk left to right with
left = 1. Setprod[i] = left, thenleft *= arr[i]. Nowprod[i]holds the left part. - Walk right to left with
right = 1. Setprod[i] *= right, thenright *= arr[i]. Nowprod[i]holds left part x right part.
The order inside each step matters: write the whisper first, then multiply in your own card, so a number never counts itself.
One walk for the left parts, one walk back for the right parts
01 / 13
The prod row starts empty. The first helper starts on the left with left = 1, because nobody stands left of index 0.
- left
- 1
- looking now
- checking
- seen
- done
- answer
- path
- just added
class Solution {
public long[] productExceptSelf(int[] arr) {
int n = arr.length;
long[] prod = new long[n];
long left = 1;
for (int i = 0; i < n; i++) {
prod[i] = left; // everything to my left
left *= arr[i]; // then add my own card
}
long right = 1;
for (int i = n - 1; i >= 0; i--) {
prod[i] *= right; // times everything to my right
right *= arr[i];
}
return prod;
}
}How long it takes: two walks, O(n). Extra room: two numbers. The answer array does not count as extra, so O(1).
Watch out for
- Updating
leftbefore writingprod[i]. Then each number multiplies itself in. - Products overflow fast. Use
long, orBigIntegerif the numbers and the length are large, or take answers modulo a prime if the problem says so. - An array of one number gives
[1]. - Keeping two extra arrays
leftProdandrightProdworks too and is easier to explain first, but it costsO(n)extra room.
What interviewers ask next
- Do it with division but handle zeros. Count zeros and multiply the nonzero numbers: zero zeros means
total / arr[i], one zero means only the zero's spot gets the product, two or more means all zeros. - The same idea with sums instead of products is just
total - arr[i]. Products are interesting because of division and zeros. - Answers modulo a prime with zeros allowed: use the prefix and suffix way, since modular division by 0 does not exist.
- Where else do left and right sweeps help? Trapping rain water (tallest wall to the left and right) and candy distribution (one pass each way).
Remember this
Grown-up words: the left whispers are prefix products, the right whispers are suffix products, and "the answer array does not count" is the usual rule for O(1) auxiliary space.