search
HomeJavajavaTutorialLeetcode : Product Of Array Except Self

This problem looks simple to solve in linear time and space. This problem builds on some of the fundamental concepts of arrays.

  1. Array traversals.
  2. 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.

Leetcode : Product Of Array Except Self

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:

Leetcode : Product Of Array Except Self

Thought process

Before writing pseudo code, come up with questions and ask the interviewer.

  1. Should I be worried about duplicates?
  2. What if the array is empty or has a single element? What are the expected results?
  3. 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.
  4. 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.

  1. Naive approach/brute-force.
  2. Product of all elements.
  3. Left and Right products.
  4. 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.

Leetcode : Product Of Array Except Self

Algorithm

  1. Initialize Variables:
    • N = nums.length (length of the input array).
    • result = new int[N] (array to store the results).
  2. Outer Loop (Iterate through each element in nums):
    • For i = 0 to N-1:Initialize currentProduct = 1.
  3. 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].
  4. 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:

Leetcode : Product Of Array Except Self

Algorithm Steps

  1. Create an array result of the same length as nums to store the final results.
  2. Create two additional arrays prefix_sum and suffix_sum of the same length as nums.
  3. 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].
  4. 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].
  5. 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].
  6. 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

  1. 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].
  2. 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

  1. Time Complexity: O(n) time
  2. 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!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Top 4 JavaScript Frameworks in 2025: React, Angular, Vue, SvelteTop 4 JavaScript Frameworks in 2025: React, Angular, Vue, SvelteMar 07, 2025 pm 06:09 PM

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

How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?Mar 17, 2025 pm 05:44 PM

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: Key Performance Boosts and New FeaturesNode.js 20: Key Performance Boosts and New FeaturesMar 07, 2025 pm 06:12 PM

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.

How does Java's classloading mechanism work, including different classloaders and their delegation models?How does Java's classloading mechanism work, including different classloaders and their delegation models?Mar 17, 2025 pm 05:35 PM

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

Spring Boot SnakeYAML 2.0 CVE-2022-1471 Issue FixedSpring Boot SnakeYAML 2.0 CVE-2022-1471 Issue FixedMar 07, 2025 pm 05:52 PM

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: The Future of Data Lake TablesIceberg: The Future of Data Lake TablesMar 07, 2025 pm 06:31 PM

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

How to Share Data Between Steps in CucumberHow to Share Data Between Steps in CucumberMar 07, 2025 pm 05:55 PM

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

How can I implement functional programming techniques in Java?How can I implement functional programming techniques in Java?Mar 11, 2025 pm 05:51 PM

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

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

mPDF

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),