LeetCode (Medium) 238. Product of Array Except Self

Nam NguyenNam Nguyen
3 min read

Description:

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.

Example 1:

Input: nums = [1,2,3,4]
Output: [24,12,8,6]

Example 2:

Input: nums = [-1,1,0,-3,3]
Output: [0,0,9,0,0]

Constraints:

  • 2 <= nums.length <= 10<sup>5</sup>

  • -30 <= nums[i] <= 30

  • The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.

Follow up:

Can you solve the problem in O(1) extra space complexity? (The output array does not count as extra space for space complexity analysis.)

Solution

To solve this problem in O(n) time and without using the division operation, we'll need to use the concept of prefix and suffix products.

First, let's work through the pseudocode:

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var productExceptSelf = function(nums) {
    // Create array for left side product
    // Create array for right side product
    // Combine both arrays to form answer array
};

Now that we have an idea of how to proceed, let's start working through the coding solution.

var productExceptSelf = function(nums) {
    let answer = []
    let leftProduct = [1]
    let rightProduct = Array(nums.length).fill(1)

    // Create array for left side product
    for (let i = 1; i < nums.length; i++){
        leftProduct[i] = leftProduct[i-1] * nums[i-1]
    }

    // Create array for right side product
    for (let i=nums.length-2; i>= 0; i--){
        rightProduct[i] = rightProduct[i+1] * nums[i+1]
    }

    // Combine both arrays to form answer array
    for (let i = 0; i < nums.length; i++){
        answer[i] = leftProduct[i] * rightProduct[i]
    }
    return answer

};

So there are a few pieces in the code we should make note of:

  1. We'll need to create three additional arrays, leftProduct, rightProduct, and answer

    1. leftProduct[i] stores the product of all the elements to the left of nums[i] (excluding nums[i])

    2. rightProduct[i] stores the product of all the elements to the right of nums[i] (excluding nums[i])

    3. answer[i] stores the product of leftProduct[i] and rightProduct[i]

  2. Once we have these arrays, we can compute the answer array in O(n) time by setting answer[i] =leftProduct[i] * rightProduct[i]. This is because the product of all the elements in the array except nums[i] is equal to the product of all the elements to the left of nums[i] multiplied by the product of all the elements to the right of nums[i].

Solution Follow-Up:

This algorithm has a time complexity of O(n) and uses O(n) extra space to store the leftProduct and rightProduct arrays. To solve the problem in O(1) extra space complexity, we can modify the above algorithm to compute the answer array in place. (Remember: The output array does not count as extra space for space complexity analysis.)

var productExceptSelf = function(nums) {
    let answer = [1]
    for (let i = 1; i < nums.length; i++){
        answer[i] = answer[i-1] * nums[i-1]
    }
    let right = 1
    for (let i = nums.length-1; i>=0; i--){
        answer[i] *= right
        right *= nums[i]
    }
    return answer
};
0
Subscribe to my newsletter

Read articles from Nam Nguyen directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nam Nguyen
Nam Nguyen

A passionate software engineer providing elegant, innovative, and accessible solutions. When I’m not click-clacking away at my keyboard, you’ll probably find me lost in a book, trying a new recipe/restaurant, or having a blast with my beautiful wife and precocious daughter. I have 10+ years of IT experience and look forward to discussing ways we can join hands for our next adventure!