Amazon Interview Question for SDE-2s


Country: India
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
3
of 5 vote

Count the number of negatives in the array, at the same time check for any zeroes in the array.

If there is a zero in the array, get the max-product from the left and right sub-arrays and find the max of them.

If there are no zeroes :
1. if no. of negatives is even, max-product is the product of all numbers.
2. if it is odd, iterate the array in both forward and backward directions and compute the product until you discover a negative number. Now, ignore the side where the product's absolute value is lesser.
eg : [ -100, 2, 25, -1, 8, -5, 22]
no. of negatives are 3 here.
When you iterate the array from both directions : fwd-product is -100 and bwd-product is -110. So ignore the values in the forward direction. So the max-product is 44000

public static int findMaxProduct(int[] array, int begin, int end) {
		int noNegs = 0; // count of negative numbers in the array
		int zeroIndex = -1; // index where a '0' is present
		for ( int i = begin; i < end; ++i) {
			if (array[i] < 0) {
				++noNegs;
			}
			if (array[i] == 0) {
				zeroIndex = i;
			}
		}
		
		if (zeroIndex > 0) {
			int l = findMaxProduct(array, begin, zeroIndex);
			int r = findMaxProduct(array, zeroIndex+1, end);
			return Math.max(l, r);
		}
		
		if (noNegs % 2 == 0) {
			int product = 1;
			for (int i = begin; i < end; ++i) {
				product *= array[i];
			}
			return product;
		}
		
		int fi, bi; // forward and backward indices
		int fp = 1, bp = 1; // forward and backward products
		for (fi = begin; fi < end; ++fi) {
			fp *= array[fi];
			if (array[fi] < 0) {
				break;
			}
		}
		for(bi = end-1; bi >= begin; --bi) {
			bp *= array[bi];
			if (array[bi] < 0) {
				break;
			}
		}
		
		int product = 1;
		int pbegin = (fp>bp) ? fi+1 : begin;
		int pend = (fp>bp) ? end : bi;
		
		for (int i = pbegin; i < pend; ++i) {
			product *= array[i];
		}
		return product;
	}

- prasanth September 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Really good sol..

- Stifler September 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Good solution. But logic for two zero's in array is missing.

- Dev October 27, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Good solution when the array is int, but not generic enough to handle double array (what if there are elements like 0.001 or -0.37); Refined version of Kadane's algorithm is more generic.

- lowiq3 September 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

To Dev, two or more zeros have already been handled here by recursion.

- lowiq3 September 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

This is a standard DP problem. Trick is to keep track of min and max of the subarray ending at i in the array indices 0 to i. While calculating the min or max, we also need to examine max or min respetively.
I'll post the code in a couple of hours.
Algorithm will be O(n)

You can see kadane's algorithm for the case of Sum. Product is just more refined problem, which uses the same algorithm.

- atuljangra66 September 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Does the problem want a subarray or just sum of the subarray?

- Yaya September 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I guess it is just the sum

- Anonymous September 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

Thank YD for reminding. I misunderstood the question.
Here's an O(n) solution for max product (inspired by the "longest valid parentheses" problem):

static int product(int A[], int begin, int end)
{
	int i, step, mh, ma;

	step = begin>end?-1:1;

	ma = A[begin]; mh = 1;
	for (i = begin; i != end; i += step) {
		mh *= A[i];
		if (mh > ma)
			ma = mh;
		if (A[i] == 0)
			mh = 1;
	}

	return ma;
}

int max_subarray_product(int A[], int n)
{
	int x, y;
	x = product(A, 0, n-1);
	y = product(A, n-1, 0);
	return x>y?x:y;
}

- Will September 13, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <stdio.h>
#include <stdlib.h>



void main (void)
{
//int tab[10]={4,5,8,0,13,-3,4,15,-2,5};
int tab[10]={4,5,5,10,-1,7,100,2,0,2000000};
int i;
int mux=1;
int max=1;
int x=0;
int pos_x=0;
int pos_y=0;

for(i=0; i<10; i++)
{


mux= mux*tab[i];

if(mux > max){
max=mux;

pos_x=x;
pos_y=i;

}
else{


if(mux==0 || mux < 0){

mux=1;
x=i+1;}

}
}


printf(" pos_x=%d and pos_y=%d \n", pos_x,pos_y);

}

- khelaf September 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1) Call the original set S. Go through set S and remove all 0s, count the negative numbers, and mark the smallest negative number. Also note if a 0 was removed. Call this new set S'
2) if there is an even number of negative numbers return the product of S'
3) if there is an odd amount of negative numbers remove the smallest negative number from S' and return the product of S'. Corner case: if the size of S' is 1 and a zero was removed, return 0.

- houseUrMusic September 18, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

edit: should be the "largest negative number"

- houseUrMusic September 18, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include<iostream>

using namespace std;

int a[31]={15,3,-10,0,-20,23,25,2,-4,19,33,-39,41,-48,37,21,65,-73,69,28,46,-88,93,52,-56,44,98,-7,-9,-100,121};

int main()
{
    int min=0;
    int c=0,t;
    for(int i=0;i<31;i++)
    {
        if(a[i]<min)
            min=a[i];
    }
    int mul=1;
    for(int i=0;i<31;i++)
    {
        if(a[i]<0)
        {
            if(min<a[i])
            {
              min=a[i];
              t=i;
            }
            c++;
        }
    }
    //cout<<min<<"\n";
    if(c%2!=0)
        a[t]=0;
     for(int i=0;i<30;i++)
    {
        if(a[i]!=0)
        {
            mul*=a[i];
        }
    }
    cout<<mul;
}

- Deepanshu October 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

We are looking for the maximum product of an array elements. It apparent that we should ignore zeros since considering zeros simplifies the problem to find the maximum product of sub-arrays that are between these zeros (if there is only one zero, the max product of its left values and right values). If this is an acceptable assumption, it is also apparent that the product of the entire array elements is the answer if there is no negative values. This is also true if there exists even number of negative values. Hence, we can check and see if there are even or odd number of negative values and find the required maximum product accordingly.

void MaxProductSubArray(int *a, int n)
{
	int cnt=0,i;
	int prod=1;
	int max=INT_MIN,I=INT_MIN;
	for(i=0;i<n;i++)
	{
		if(a[i]<0)
			cnt++;
		if(a[i]!=0)
			prod*=a[i];
	}
	if(cnt%2==0)
		printf("%d\n",prod);
	else
	{
		for(i=0;i<n;i++)
		{
			if(a[i]<0)
			{
				if(prod/a[i]>max)
				{
					max=prod/a[i];
					I=i;
					printf("---> %d\t%d\n",i,a[i]);
				}
			}
		}
		printf("\nMAX:\t%d\n",max);
	}
}

}

- Anonymous October 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

My code that passed Leetcode OJ:

Explanations in changhaz(dot)wordpress(dot)com

class Solution {
public:
int maxProduct(int A[], int n) {
if (n==0) return 0;

int maxi = 1, mini = 1;
int out = INT_MIN;

for (int i=0;i<n;i++) {
int oldmaxi = max(maxi,1);
if (A[i] > 0) {
maxi = oldmaxi*A[i];
mini *= A[i];
} else {
maxi = mini*A[i];
mini = oldmaxi*A[i];
}
out = max(out,maxi);
}

return out;
}
};

- changhaz September 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Take a logarithm of each number, at this point the problem reduces to largest sum of subarray problem, which can be easily solves with Kadane's algorithm.

If the interviewer insists on using integers, the problem can be solved with a modified Kadane's algorithm, which keeps track of the largest and smallest product.

- Anonymous September 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

For an array with both positive and negative numbers we can notice that:
1. zero is to be ignored unless the array contains exactly 2 numbers {-v, 0}
2. Positive numbers are always wanted
3. Negative numbers are wanted as long as there is an even number of them
and in this case you want the smallest ones so to create the largest positive
product of them.

Because of the mixture you have to start by sorting them o(nlogn)
once sorted you can find the answer in a single scan of the sorted array while:
1. keeping track of the number negative numbers - ignore the biggest (closest to zero) negative number if there is an odd number of negative numbers.
2. Ignore 0 if possible (only one case require the use of 0)
3. Once reaching at the positive numbers continue to calculate till the end.

- YD September 09, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

for(i=0;i<n;i++)
	{
		if(a[i]!=0)
		{
		if(currValue*a[i]>curValue)
			maxProd=(curValue*a[i]>maxProd?currValue*a[i]:maxProd);		
		curValue=curValue*a[i];
		}
	}
	return max;

- Anonymous September 10, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This wont work for everything, here are some examples it will fail for:
1. The array {-1,0} --> the mux product is 0, your code ignores 0
2. {-2,-1,-9} --> So the question is do we have to find a solution of consecutive numbers In the array or just select the best numbers to include. for the first option that will be {-1,-9} for the seconds it is {-2, -9}

- YD September 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
-2
of 2 vote

An O(n) solution:

int max_subarray(int A[], int n)
{
	int i, mh, ma;
	mh = ma = A[0];
	for (i = 1; i < n; i++) {
		mh += A[i];
		if (mh < A[i])
			mh = A[i];
		if (mh > ma)
			ma = mh;
	}
	return ma;
}

- Will September 10, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

But the question was about the product and not sum

- YD September 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
Comment hidden because of low score. Click to expand.
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Nitin: No, he's considering all the cases. Let me explain his strategy with an example,

[1, -2, 3, 4, -5, 0, 2, 5, 1, 0, 8, -3, 1, 0, 0, 1, 3, -5, 7, -6, 2, -2, 2]

Consider all maximal non-zero subarrays:

[1, -2, 3, 4, -5]: there are 2(even) -ve numbers so take the product as it is, i.e. 120

[2, 5, 1]: there are 0(even) -ve numbers so take the product as it is: 10

[8, -3, 1]: there is 1(odd) -ve numbers, so take the two positive products, i.e. 8 and 1

[1, 3, -5, 7, -6, 2, -2, 4]: there are 3(odd) -ve numbers, so take the two biggest positive products, i.e 1 to -2 = 1260 and 7 to 4 = 672

Clearly the biggest product is 1260.

I just want to mention one thing: initialize the maximum global sum to -infinity. If there is at least one zero in the array, initialize it to 0.

- anotherguy September 08, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 3 votes

@Nitin R. Gupta

Seems you have barely understood the algorithm. See @anotherguy's comments for an explanation.

- Murali Mohan September 08, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sounds good, except step 2 should contain a third case for which there is only one number, which is negative, between begin and end.

- Anonymous September 08, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Erasmus:
What if you have an array with all negatives? You are not considering any negative products, so your answer will be undefined in this case.

I think we should initialize the max. global sum to -infinity, then consider all positive products as you suggested, and all non-positive numbers individually as well!

- anotherguy September 08, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 3 votes

@anotherguy

You have got a nice use-case, the one with all -ve numbers. In this case, you would not want to check all non-positive numbers individually. Instead, It again boils down to whether you have an even number of -ve numbers or an odd number of them.

If the count parity is even, you will get maximum subarray positive product by multiplying all of the -ve numbers.

If the count parity is odd, you will get maximum subarray positive product by either multiplying from 0 to n-2 or from 1 to n-1

Both of the above cases are anyway handled by my algorithm in step 2 (and beyond) as show below
>>2. Between begin and end, take the count, c of the number of -ve numbers and note the 'first'and 'last' positions of -ve numbers

However, to address your issue, I need to slightly modify my procedure of demarcating the 'end' of the array in the step 1. The below statement can be changed from:
>> 1. From 'begin' traverse the array until you find a 0 and demarcate it as 'end'.

to:

>> 1. From 'begin' traverse the array until you find a 0 or reach the end of the array and demarcate it as 'end'.

However, the un-handled test case suggested by @Anonymous is more fundamental and is the one which indeed requires checking all -ve numbers individually. For ex: if we you have the array [0,-1,0,-2,0,-3,0], you will have to check each -ve number individually and pick the min of them to give you the maximum subarray (-ve) product.

@Anonymous
Excellent test case, thanks! For your type of input, say [0,-1,0]. my algorithm may not crash, but it would wrongly return 0. Instead, it should return -1 and yes, step 2 certainly needs modification.

When there are odd number of -ve numbers between begin and end, with an additional check to see if there is only one element between begin and end, we can return the lone -ve number's value itself as the max product of the subarray.

- Murali Mohan September 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
Comment hidden because of low score. Click to expand.
0
of 0 votes

This will not work for mix of positive and negative numbers.

- Aadish Kotwal September 08, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Does not work, even for positive numbers.

Just tried running your code with {1, 2, 3, 0, 4, 5}, gives 120

- anotherguy September 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@ anotherguy 120 for the array {1,2,3,0,4,5} is a correct outcome since the question is asking for a maximum sub-array and not a maximum sequence i.e., it is not concern if the values are sequential.
@Aadish, would you please explain why you suggest so? I tried it on {1, -2, 3, 4, -5, 0} and {1, -2, 3, 4, -5, 0, 2, 5, 1, 0, 8, -3, 1, 0, 0, 1, 3, -5, 7, -6, 2, -2, 2}. Thanks! :)

- Anonymous September 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
Comment hidden because of low score. Click to expand.


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More