Product of Array Except Self
Problem Statement
Section titled “Problem Statement”Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i]. The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer. You must write an algorithm that runs in O(n) time and without using the division operation.
Examples
Section titled “Examples”| Input | Output |
|---|---|
[1,2,3,4] | [24,12,8,6] |
[-1,1,0,-3,3] | [0,-9,0,9,0] |
Constraints
Section titled “Constraints”2 <= nums.length <= 10^5-30 <= nums[i] <= 30- The product of any prefix or suffix fits in a 32-bit integer
Real-World Applications
Section titled “Real-World Applications”Complexity Comparison
Section titled “Complexity Comparison”| Approach | Time | Space | Best When |
|---|---|---|---|
| Prefix/Suffix Arrays | O(n) | O(n) | Clarity matters, extra memory allowed |
| Two-Pass (O(1) space) | O(n) | O(1)* | Follow-up requirement, memory-constrained |
*The output array is not counted as extra space per the problem convention.
Approach 1: Prefix/Suffix Arrays
Section titled “Approach 1: Prefix/Suffix Arrays”Build a prefix array where prefix[i] is the product of all elements to the left of index i, and a suffix array where suffix[i] is the product of all elements to the right of index i. The answer at each index is simply prefix[i] * suffix[i].
Step-by-step Example
Section titled “Step-by-step Example”Input: [1, 2, 3, 4]
| i | prefix[i] | suffix[i] | output[i] |
|---|---|---|---|
| 0 | 1 | 24 | 24 |
| 1 | 1 | 12 | 12 |
| 2 | 2 | 4 | 8 |
| 3 | 6 | 1 | 6 |
Animated walkthrough
Use Next or Autoplay to watch the prefix array fill left→right, then the suffix array fill right→left, before combining them.
Pseudocode
Section titled “Pseudocode”function productExceptSelf(nums): n = len(nums) prefix = [1] * n suffix = [1] * n for i in range(1, n): prefix[i] = prefix[i-1] * nums[i-1] for i in range(n-2, -1, -1): suffix[i] = suffix[i+1] * nums[i+1] return [prefix[i] * suffix[i] for i in range(n)]Solution Code
Section titled “Solution Code”from typing import List
def product_except_self(nums: List[int]) -> List[int]: n = len(nums) prefix = [1] * n suffix = [1] * n
for i in range(1, n): prefix[i] = prefix[i - 1] * nums[i - 1]
for i in range(n - 2, -1, -1): suffix[i] = suffix[i + 1] * nums[i + 1]
return [prefix[i] * suffix[i] for i in range(n)]#include <vector>using namespace std;
class Solution {public: vector<int> productExceptSelf(vector<int>& nums) { int n = nums.size(); vector<int> prefix(n, 1); vector<int> suffix(n, 1);
for (int i = 1; i < n; ++i) prefix[i] = prefix[i - 1] * nums[i - 1];
for (int i = n - 2; i >= 0; --i) suffix[i] = suffix[i + 1] * nums[i + 1];
vector<int> output(n); for (int i = 0; i < n; ++i) output[i] = prefix[i] * suffix[i];
return output; }};class Solution { public int[] productExceptSelf(int[] nums) { int n = nums.length; int[] prefix = new int[n]; int[] suffix = new int[n]; prefix[0] = 1; suffix[n - 1] = 1;
for (int i = 1; i < n; i++) prefix[i] = prefix[i - 1] * nums[i - 1];
for (int i = n - 2; i >= 0; i--) suffix[i] = suffix[i + 1] * nums[i + 1];
int[] output = new int[n]; for (int i = 0; i < n; i++) output[i] = prefix[i] * suffix[i];
return output; }}/** * @param {number[]} nums * @return {number[]} */function productExceptSelf(nums) { const n = nums.length; const prefix = new Array(n).fill(1); const suffix = new Array(n).fill(1);
for (let i = 1; i < n; i++) prefix[i] = prefix[i - 1] * nums[i - 1];
for (let i = n - 2; i >= 0; i--) suffix[i] = suffix[i + 1] * nums[i + 1];
return Array.from({ length: n }, (_, i) => prefix[i] * suffix[i]);}impl Solution { pub fn product_except_self(nums: Vec<i32>) -> Vec<i32> { let n = nums.len(); let mut prefix = vec![1i32; n]; let mut suffix = vec![1i32; n];
for i in 1..n { prefix[i] = prefix[i - 1] * nums[i - 1]; }
for i in (0..n - 1).rev() { suffix[i] = suffix[i + 1] * nums[i + 1]; }
(0..n).map(|i| prefix[i] * suffix[i]).collect() }}func productExceptSelf(nums []int) []int { n := len(nums) prefix := make([]int, n) suffix := make([]int, n) prefix[0] = 1 suffix[n-1] = 1
for i := 1; i < n; i++ { prefix[i] = prefix[i-1] * nums[i-1] }
for i := n - 2; i >= 0; i-- { suffix[i] = suffix[i+1] * nums[i+1] }
output := make([]int, n) for i := 0; i < n; i++ { output[i] = prefix[i] * suffix[i] }
return output}Approach 2: Two-Pass O(1) Space
Section titled “Approach 2: Two-Pass O(1) Space”Reuse the output array itself instead of allocating separate prefix and suffix arrays. The first pass (left→right) fills each slot with the running prefix product. The second pass (right→left) multiplies each slot by a running suffix product variable.
Step-by-step Example
Section titled “Step-by-step Example”Input: [1, 2, 3, 4]
After pass 1 (left prefix into output): output = [1, 1, 2, 6]
Pass 2 (right→left, running suffix starts at 1):
| i | output[i] before | suffix | output[i] after | suffix update |
|---|---|---|---|---|
| 3 | 6 | 1 | 6×1 = 6 | 1×4 = 4 |
| 2 | 2 | 4 | 2×4 = 8 | 4×3 = 12 |
| 1 | 1 | 12 | 1×12 = 12 | 12×2 = 24 |
| 0 | 1 | 24 | 1×24 = 24 | — |
Result: [24, 12, 8, 6]
Animated walkthrough
Pass 1 fills the output with left-prefix products. Pass 2 multiplies in right-suffix products using a single variable.
Pseudocode
Section titled “Pseudocode”function productExceptSelfOptimal(nums): n = len(nums) output = [1] * n prefix = 1 for i in range(n): output[i] = prefix prefix *= nums[i] suffix = 1 for i in range(n-1, -1, -1): output[i] *= suffix suffix *= nums[i] return outputSolution Code
Section titled “Solution Code”from typing import List
def product_except_self(nums: List[int]) -> List[int]: n = len(nums) output = [1] * n
prefix = 1 for i in range(n): output[i] = prefix prefix *= nums[i]
suffix = 1 for i in range(n - 1, -1, -1): output[i] *= suffix suffix *= nums[i]
return output#include <vector>using namespace std;
class Solution {public: vector<int> productExceptSelf(vector<int>& nums) { int n = nums.size(); vector<int> output(n, 1);
int prefix = 1; for (int i = 0; i < n; ++i) { output[i] = prefix; prefix *= nums[i]; }
int suffix = 1; for (int i = n - 1; i >= 0; --i) { output[i] *= suffix; suffix *= nums[i]; }
return output; }};class Solution { public int[] productExceptSelf(int[] nums) { int n = nums.length; int[] output = new int[n];
int prefix = 1; for (int i = 0; i < n; i++) { output[i] = prefix; prefix *= nums[i]; }
int suffix = 1; for (int i = n - 1; i >= 0; i--) { output[i] *= suffix; suffix *= nums[i]; }
return output; }}/** * @param {number[]} nums * @return {number[]} */function productExceptSelf(nums) { const n = nums.length; const output = new Array(n).fill(1);
let prefix = 1; for (let i = 0; i < n; i++) { output[i] = prefix; prefix *= nums[i]; }
let suffix = 1; for (let i = n - 1; i >= 0; i--) { output[i] *= suffix; suffix *= nums[i]; }
return output;}impl Solution { pub fn product_except_self(nums: Vec<i32>) -> Vec<i32> { let n = nums.len(); let mut output = vec![1i32; n];
let mut prefix = 1; for i in 0..n { output[i] = prefix; prefix *= nums[i]; }
let mut suffix = 1; for i in (0..n).rev() { output[i] *= suffix; suffix *= nums[i]; }
output }}func productExceptSelf(nums []int) []int { n := len(nums) output := make([]int, n)
prefix := 1 for i := 0; i < n; i++ { output[i] = prefix prefix *= nums[i] }
suffix := 1 for i := n - 1; i >= 0; i-- { output[i] *= suffix suffix *= nums[i] }
return output}Approach 3: Space-Optimized Variant
Section titled “Approach 3: Space-Optimized Variant”A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.
Pseudocode
Section titled “Pseudocode”function approach3(): // Implementation approach goes hereSolution Code
Section titled “Solution Code”"""Solution for Product of Array Except Self"""
def solve(): """Implementation for approach 3 of Product of Array Except Self""" pass
if __name__ == "__main__": print("Solution ready")#include <bits/stdc++.h>using namespace std;
// Solution for Product of Array Except Self// Approach 3: Implementation
int main() {{ // Main implementation goes here return 0;}}/** * Solution for Product of Array Except Self * Approach 3 */public class ProductOfArrayExceptSelfSpaceOptimized {{
public static void main(String[] args) {{ // Implementation goes here }}}}/** * Solution for Product of Array Except Self * Approach 3 */
function solve() {{ // Implementation goes here}}
module.exports = solve;/// Solution for Product of Array Except Self/// Approach 3
fn main() {{ println!("Solution implementation");}}package main
import "fmt"
// Solution for Product of Array Except Self// Approach 3
func main() {{ fmt.Println("Solution implementation")}}