This problem looks simple to solve in linear time and space. This problem builds on some of the fundamental concepts of arrays.
- Array traversals.
- Prefix and Suffix sum.
Companies that have asked this in their coding interview are Facebook, Amazon, Apple, Netflix, Google, Microsoft, Adobe, and many more top tech companies.
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.
Test case#1:
Input: nums = [1,2,3,4] Output: [24,12,8,6]
Test case#2:
Input: nums = [-1,1,0,-3,3] Output: [0,0,9,0,0]
Understanding the problem
This problem looks simpler to solve in linear time and space, but it is tricky when writing the pseudocode or actual code implementation.
Illustration
Let us see what the results that are expected from a simple array containing 4 elements:
input = {1, 2, 3, 4}
So, the value at each index is the product of all the other elements in the array except the value itself. The following figure illustrates this.
Based on the above figure, we can come up with a formula. For any given index i, we can find the value using the product of the elements from o to (i - 1) plus product of elements from (i 1) to (N - 1). This is illustrated in the following figure:
Thought process
Before writing pseudo code, come up with questions and ask the interviewer.
- Should I be worried about duplicates?
- What if the array is empty or has a single element? What are the expected results?
- Should I consider/ignore 0 value in any of the indexes in the array? because all other values get 0 except the index containing 0.
- What are the corner/edge cases for this problem?
Once you and the interviewer have discussed the above questions, devise various approaches to solving the problem.
- Naive approach/brute-force.
- Product of all elements.
- Left and Right products.
- Prefix and suffix sums.
Approach 1: Naive/Brute-force
Intuition
To employ the brute force approach, we must execute two for-loops. When the outer loop index matches the inner loop index value, we should skip the product; otherwise, we proceed with the product.
Algorithm
- Initialize Variables:
- N = nums.length (length of the input array).
- result = new int[N] (array to store the results).
- Outer Loop (Iterate through each element in nums):
- For i = 0 to N-1:Initialize currentProduct = 1.
- Inner Loop (Calculate product for current element), for j = 0 to N-1:
- If i == j, skip the current iteration using continue.
- Multiply currentProduct by nums[j].
- Assign currentProduct to result[i].
- Return result.
Code
// brute force static int[] bruteForce(int[] nums) { int N = nums.length; int[] result = new int[N]; for (int i = 0; i <h3> Complexity analysis </h3> <ol> <li> <strong>Time complexity</strong>: O(n^2), for iterating the array twice in outer and inner loops.</li> <li> <strong>Space complexity</strong>: O(n), for the auxiliary space (result[] array) we used.</li> </ol> <h2> Approach 2: Product of array ❌ </h2> <p>One way most developers think is to run a product sum of all elements, divide the product sum by each array value, and return the result.</p> <h3> Pseudocode </h3> <pre class="brush:php;toolbar:false">// O(n) time and O(1) space p = 1 for i -> 0 to A[i] p * = A[i] for i -> 0 to (N - 1) A[i] = p/A[i] // if A[i] == 0 ? BAM error‼️
Code
// code implementation static int[] productSum(int[] nums) { int product_sum = 1; for(int num: nums) { product_sum *= num; } for(int i = 0; i <p>What if one of the array elements contain 0? ?</p> <p>The value at all the indexes except the index containing 0 will definitely be infinity. Also, the code throws java.lang.ArithmeticException.<br> </p> <pre class="brush:php;toolbar:false">Exception in thread "main" java.lang.ArithmeticException: / by zero at dev.ggorantala.ds.arrays.ProductOfArrayItself.productSum(ProductOfArrayItself.java:24) at dev.ggorantala.ds.arrays.ProductOfArrayItself.main(ProductOfArrayItself.java:14)
Approach 3: Find Prefix and Suffix product
Learn more about prefix and suffix sum in the Arrays Mastery Course on my website https://ggorantala.dev
Intuition & formulae's
Prefix and Suffix are calculated before writing an algorithm for the result. Prefix and Suffix sum formulae are given below:
Algorithm Steps
- Create an array result of the same length as nums to store the final results.
- Create two additional arrays prefix_sum and suffix_sum of the same length as nums.
- Calculate Prefix Products:
- Set the first element of prefix_sum to the first element of nums.
- Iterate through the input array nums starting from the second element (index 1). For each index i, set prefix_sum[i] to the product of prefix_sum[i-1] and nums[i].
- Calculate Suffix Products:
- Set the last element of suffix_sum to the last element of nums.
- Iterate through the input array nums starting from the second-to-last element (index nums.length - 2) to the first element. For each index i, set suffix_sum[i] to the product of suffix_sum[i+1] and nums[i].
- Calculate the result: Iterate through the input array nums.
- For the first element (i == 0), set result[i] to suffix_sum[i + 1].
- For the last element (i == nums.length - 1), set result[i] to prefix_sum[i - 1].
- For all other elements, set result[i] to the product of prefix_sum[i - 1] and suffix_sum[i + 1].
- Return the result array containing the product of all elements except the current element for each index.
Pseudocode
Function usingPrefixSuffix(nums): N = length of nums result = new array of length N prefix_sum = new array of length N suffix_sum = new array of length N // Calculate prefix products prefix_sum[0] = nums[0] For i from 1 to N-1: prefix_sum[i] = prefix_sum[i-1] * nums[i] // Calculate suffix products suffix_sum[N-1] = nums[N-1] For i from N-2 to 0: suffix_sum[i] = suffix_sum[i+1] * nums[i] // Calculate result array For i from 0 to N-1: If i == 0: result[i] = suffix_sum[i+1] Else If i == N-1: result[i] = prefix_sum[i-1] Else: result[i] = prefix_sum[i-1] * suffix_sum[i+1] Return result
Code
// using prefix and suffix arrays private static int[] usingPrefixSuffix(int[] nums) { int[] result = new int[nums.length]; int[] prefix_sum = new int[nums.length]; int[] suffix_sum = new int[nums.length]; // prefix sum calculation prefix_sum[0] = nums[0]; for (int i = 1; i = 0; i--) { suffix_sum[i] = suffix_sum[i + 1] * nums[i]; } for (int i = 0; i <h3> Complexity analysis </h3> <ol> <li> <strong>Time complexity</strong>: The time complexity of the given code is O(n), where n is the length of the input array nums. This is because: <ul> <li>Calculating the prefix_sum products take O(n) time.</li> <li>Calculating the suffix_sum products take O(n) time.</li> <li>Constructing the result array takes O(n) time.</li> </ul> </li> </ol> <p>Each of these steps involves a single pass through the array, resulting in a total time complexity of O(n)+O(n)+O(n) = 3O(n), which is O(n).</p> <ol> <li> <strong>Space complexity</strong>: The space complexity of the given code is O(n). This is because: <ul> <li>The prefix_sum array requires O(n) space.</li> <li>The suffix_sum array requires O(n) space.</li> <li>Theresult array requires O(n) space. All three arrays are of length n, so the total space complexity is O(n) + O(n) + O(n) = 3O(n), which is O(n).</li> </ul> </li> </ol> <h3> Optimization ? </h3> <p>For the suffix array calculation, we override the input nums array instead of creating one.<br> </p> <pre class="brush:php;toolbar:false">private static int[] usingPrefixSuffixOptimization(int[] nums) { int[] result = new int[nums.length]; int[] prefix_sum = new int[nums.length]; // prefix sum calculation prefix_sum[0] = nums[0]; for (int i = 1; i = 0; i--) { nums[i] = nums[i + 1] * nums[i]; } for (int i = 0; i <p>Hence, we reduced the space of O(n). Time and space are not reduced, but we did a small optimization here.</p> <h2> Approach 4: Using Prefix and Suffix product knowledge ? </h2> <h3> Intuition </h3> <p>This is a rather easy approach when we use the knowledge of prefix and suffix arrays.</p> <p>For every given index i, we will calculate the product of all the numbers to the left and then multiply it by the product of all the numbers to the right. This will give us the product of all the numbers except the one at the given index i. Let's look at a formal algorithm that describes this idea more clearly.</p> <h3> Algorithm steps </h3> <ol> <li>Create an array result of the same length as nums to store the final results.</li> <li>Create two additional arrays prefix_sum and suffix_sum of the same length as nums.</li> <li>Calculate Prefix Products: <ul> <li>Set the first element of prefix_sum to 1.</li> <li>Iterate through the input array nums starting from the second element (index 1). For each index i, set prefix_sum[i] to the product of prefix_sum[i - 1] and nums[i - 1].</li> </ul> </li> <li>Calculate Suffix Products: <ul> <li>Set the last element of suffix_sum to 1.</li> <li>Iterate through the input array nums starting from the second-to-last element (index nums.length - 2) to the first element.</li> <li>For each index i, set suffix_sum[i] to the product of suffix_sum[i + 1] and nums[i + 1].</li> </ul> </li> <li>Iterate through the input array nums. <ul> <li>For each index i, set result[i] to the product of prefix_sum[i] and suffix_sum[i].</li> </ul> </li> <li>Return the result array containing the product of all elements except the current element for each index.</li> </ol> <h3> Pseudocode </h3> <pre class="brush:php;toolbar:false">Function prefixSuffix1(nums): N = length of nums result = new array of length N prefix_sum = new array of length N suffix_sum = new array of length N // Calculate prefix products prefix_sum[0] = 1 For i from 1 to N-1: prefix_sum[i] = prefix_sum[i-1] * nums[i-1] // Calculate suffix products suffix_sum[N-1] = 1 For i from N-2 to 0: suffix_sum[i] = suffix_sum[i+1] * nums[i+1] // Calculate result array For i from 0 to N-1: result[i] = prefix_sum[i] * suffix_sum[i] Return result
Code
private static int[] prefixSuffixProducts(int[] nums) { int[] result = new int[nums.length]; int[] prefix_sum = new int[nums.length]; int[] suffix_sum = new int[nums.length]; prefix_sum[0] = 1; for (int i = 1; i = 0; i--) { suffix_sum[i] = suffix_sum[i + 1] * nums[i + 1]; } for (int i = 0; i <h3> Complexity analysis </h3> <ol> <li> <strong>Time complexity</strong>: The time complexity of the given code is O(n), where n is the length of the input array nums. This is because: <ul> <li>Calculating the prefix_sum products take O(n) time.</li> <li>Calculating the suffix_sum products take O(n) time.</li> <li>Constructing the result array takes O(n) time.</li> </ul> </li> </ol> <p>Each of these steps involves a single pass through the array, resulting in a total time complexity of O(n)+O(n)+O(n) = 3O(n), which is O(n).</p> <ol> <li> <strong>Space complexity</strong>: The space complexity of the given code is O(n). This is because: <ul> <li>The prefix_sum array requires O(n) space.</li> <li>The suffix_sum array requires O(n) space.</li> <li>The result array requires O(n) space.</li> </ul> </li> </ol> <p>All three arrays are of length n, so the total space complexity is O(n) + O(n) + O(n) = 3O(n), which is O(n).</p> <h2> Approach 5: Carry Forward technique </h2> <h3> Intuition </h3> <p>The carry forward technique optimizes us to solve the problem with a more efficient space complexity. Instead of using two separate arrays for prefix and suffix products, we can use the result array itself to store intermediate results and use a single pass for each direction.</p> <p>Here’s how you can implement the solution using the carry-forward technique:</p> <h3> Algorithm Steps for Carry Forward Technique </h3> <ol> <li>Initialize Result Array: <ul> <li>Create an array result of the same length as nums to store the final results.</li> </ul> </li> <li>Calculate Prefix Products: <ul> <li>Initialize a variable prefixProduct to 1.</li> <li>Iterate through the input array nums from left to right. For each index i, set result[i] to the value of prefixProduct. Update prefixProduct by multiplying it with nums[i].</li> </ul> </li> <li>Calculate Suffix Products and Final Result: <ul> <li>Initialize a variable suffixProduct to 1.</li> <li>Iterate through the input array nums from right to left. For each index i, update result[i] by multiplying it with suffixProduct. Update suffixProduct by multiplying it with nums[i].</li> </ul> </li> <li>Return the result array containing the product of all elements except the current element for each index.</li> </ol> <h3> Pseudocode </h3> <pre class="brush:php;toolbar:false">prefix products prefixProduct = 1 For i from 0 to N-1: result[i] = prefixProduct prefixProduct = prefixProduct * nums[i] // Calculate suffix products and finalize result suffixProduct = 1 For i from N-1 to 0: result[i] = result[i] * suffixProduct suffixProduct = suffixProduct * nums[i] Return result
Code
// carry forward technique private static int[] carryForward(int[] nums) { int n = nums.length; int[] result = new int[n]; // Calculate prefix products int prefixProduct = 1; for (int i = 0; i = 0; i--) { result[i] *= suffixProduct; suffixProduct *= nums[i]; } return result; }
Explanation
- Prefix Products Calculation:
- We initialize prefixProduct to 1 and update each element of result with the current value of prefixProduct.
- Update prefixProduct by multiplying it with nums[i].
- Suffix Products Calculation:
- We initialize suffixProduct to 1 and update each element of result(which already contains the prefix product) by multiplying it with suffixProduct.
- Update suffixProduct by multiplying it with nums[i].
Complexity analysis
- Time Complexity: O(n) time
- Space Complexity: O(n) (for the result array)
This approach uses only a single extra array (result) and two variables (prefixProduct and suffixProduct), achieving efficient space utilization while maintaining O(n) time complexity.
The above is the detailed content of Leetcode : Product Of Array Except Self. For more information, please follow other related articles on the PHP Chinese website!

This article analyzes the top four JavaScript frameworks (React, Angular, Vue, Svelte) in 2025, comparing their performance, scalability, and future prospects. While all remain dominant due to strong communities and ecosystems, their relative popul

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

Node.js 20 significantly enhances performance via V8 engine improvements, notably faster garbage collection and I/O. New features include better WebAssembly support and refined debugging tools, boosting developer productivity and application speed.

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa

This article addresses the CVE-2022-1471 vulnerability in SnakeYAML, a critical flaw allowing remote code execution. It details how upgrading Spring Boot applications to SnakeYAML 1.33 or later mitigates this risk, emphasizing that dependency updat

Iceberg, an open table format for large analytical datasets, improves data lake performance and scalability. It addresses limitations of Parquet/ORC through internal metadata management, enabling efficient schema evolution, time travel, concurrent w

This article explores methods for sharing data between Cucumber steps, comparing scenario context, global variables, argument passing, and data structures. It emphasizes best practices for maintainability, including concise context use, descriptive

This article explores integrating functional programming into Java using lambda expressions, Streams API, method references, and Optional. It highlights benefits like improved code readability and maintainability through conciseness and immutability


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

Dreamweaver Mac version
Visual web development tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SublimeText3 Mac version
God-level code editing software (SublimeText3)

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),
