left[i] = product of nums[0..i−1], right[i] = product of nums[i+1..n−1]. answer[i] = left[i] × right[i].
Approach 1
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] left = new int[n], right = new int[n], out = new int[n];
left[0] = 1;
for (int i = 1; i < n; i++) left[i] = left[i - 1] * nums[i - 1];
right[n - 1] = 1;
for (int i = n - 2; i >= 0; i--) right[i] = right[i + 1] * nums[i + 1];
for (int i = 0; i < n; i++) out[i] = left[i] * right[i];
return out;
}
}
Verdict: Clear, with two extra arrays.
2
Optimal: prefix in the output, suffix in a variable
Time O(n) Space O(1) extra (the output doesn't count)
First pass writes left products into the answer. Second pass goes right to left with a running suffix product, multiplying it in.
▶ Dry run: Left pass, then right passnums = [1, 2, 3, 4]
1
a0
1
a1
2
a2
6
a3
Step 1/5Left pass: answer[i] = product of everything before i: [1, 1, 1·2, 1·2·3].
Approach 2
class Solution {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] out = new int[n];
out[0] = 1;
for (int i = 1; i < n; i++) out[i] = out[i - 1] * nums[i - 1];
int suffix = 1;
for (int i = n - 1; i >= 0; i--) {
out[i] *= suffix;
suffix *= nums[i];
}
return out;
}
}
Verdict: Same idea, no extra arrays.
Before you submit
Edge cases and common mistakes
Test these inputs
One zero (only that index is non-zero)
Two or more zeros (all zeros)
Negative numbers
Length 2
Mistakes people make
Using total product / nums[i]: banned, and divides by zero.