## DEV Community 👩‍💻👨‍💻 is a community of 966,155 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Akhil

Posted on

# Product of array except self, a mind-boggling Google Interview question

Question: Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

Eg :

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

Seems pretty easy right? Just multiply all the numbers then divide each one to get the result.

Solve it without division and in O(n) time.

At first I was bit intermediate and I spent a lot of time figeuring it out but the solution is straight forward.

Tip: Always remember this principle

## KEEP IT SIMPLE STUPID

End result is, for an index i we want product of all elements from 0 to i-1 and i+1 to n

So let's divide our problem into two sub-problems:

1> Find the product of all elements less than the current element.
2> Find the product of all elements greater than the current element.

The product of these two subproblems will give us the final result.

So for all elements less than i, let's keep it in array called left[];

`````` left[]=      1      1*arr[0]   1*arr[0]*arr[1]     1*arr[0]*arr[1]*arr[2]
arr[0]     arr[1]        arr[2]                  arr[3]
``````

converting it to code:

``````   let left = [];
let mul = 1;                 //keeping track of multiplication
for(let i=0;i<nums.length;i++){
left[i] = mul;
mul = mul*nums[i];
}
``````

Similarly for elements more than the current element. let's call it right[]

`````` right[]= 1*arr[1]*arr[2]*arr[3]   1*arr[2]*arr[3]       1*arr[3]       1
arr[0]                  arr[1]              arr[2]      arr[3]
``````

Converting that to code :

``````   let right = [];
let mul = 1;                 //keeping track of multiplication
for(let i=nums.length-1;i>=0;i++){
right[i] = mul;
mul = mul*nums[i];
}
``````

After this, the only step is to put the two arrays together.

``````   let res = [];
for(let i=0;i<nums.length;i++){
res[i] = left[i]*right[i];
}
return res;
``````

Now, let's optimize this, here we're using 3 arrays in total, one for all elements less than i, one for all elements greater than i, and one for the final result.

Let's trim some fat and reduce this to a single array.

We have iterate twice on the array, one from left to right to get the multiplication of all elements less than the current index and once from right to left to get multiplication of all elements greater than the current index one.

Cinverting it to code :

``````var productExceptSelf = function(nums) {
let res = [];
let left = 1;
let right = 1;
for(let i=0;i<nums.length;i++){
res[i] = left;
left = left*nums[i];
}

for(let i=nums.length-1;i>=0;i--){
res[i] = right*res[i];
right = right*nums[i];
}
return res;
};
``````

I hope you liked my explanation :)

Pedro Pimenta • Edited on

EDIT: I guess I don't know what O(n) is? :)

I am probalby not understanding something, but wouldn't this work?

``````const baseArray = [1, 2, 3, 4]
const newArray = []

console.log(baseArray)

for (let i in baseArray) {
let total = 1
for (let p in baseArray) {
if (i !== p) {
total = total * baseArray[p]
}
}
newArray.push(total)
}

console.log(newArray)
``````

I did it here: jsbin.com/zawuwugagu/edit?js,console

Akhil

It works, but your algorithm works in O(n^2). The solution in article works in O(n).

Pedro Pimenta

Yeah I get it now. I'm not a programmer by education, so I don't know many of these concepts. I guess O(n) means going through the array only once, right? I go through the array as many times as elements are in the array, hence O(n^2). This is not performant, your solution (and the one asked for, actually) is resolved quicker and with less processing power. Hey, I learned something, right? :D Thanks!

Akhil

Spot on! I will add your solution too so that people like you can get a better idea about performance :D

Carlos Balbuena

Cool explanation. But getting this result quickly in an interview is challenging

Akhil

yea, I had to spend like 30 mins figuring out which data structure to use, and other random ideas. Some of the questions like these can be solved only if candidate has already seen something similar before.

Carlos Balbuena

Agree with you. But maybe we need to memorize / learn patterns instead of solutions. Thats what im doing now to prepare for my next interviews