Amazon Interview Question for Software Engineer / Developers


Country: India
Interview Type: In-Person




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

I think simple kadane's algorithm is enough to solve this pbm :)

Find the distance between petrol and distance (p-d) and create one array. After that apply kadane's algorithm for maximum sum :)

- NoMind January 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Will you plz explain a little more ? Suppose I have found the max sum, but what will be the approach after that ? Thanks in advance.

- Shah January 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Kadane's algorithm
Initialize:
max_so_far = 0
max_ending_here = 0

Loop for each element of the array
(a) max_ending_here = max_ending_here + a[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far

- NoMind February 02, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

In this case you would not be taking into account the distance between the current station and the next station.
You choose the next max available, but what if the distance to that max can not be traversed with the current petrol state.

- Anonymous February 11, 2013 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

Approach:
Let D be the distance array.
Let P be the petrol array.
int [] D = {4, 7, 4, 8, 4, 1};
int [] P = {3, 5, 3, 8, 3, 6};


Now start with i=0;
D[0] = 4 > P[0] = 3; i=0 can not be starting point so we move to i=1;
D[1] = 7 > P[1] = 5; i=1 can not be starting point So we move to i=2;
D[2] = 4 > P[2] = 3; i=2 can not be starting pointso we move to i=3;
D[3] = 8 <= P[3] = 8; i=3 can be starting point, now keep on summing the D[i] and P[i] and P[i] >= D[i]
D[4] = 4 > P[4] = 3; here the P[i] is not greater or equal to D[i] so we break; and start from next i=5;


D[5]=1 < P[5] = 6; and carry over petrol is 5
now,
D[0] = 4 < P[0] + carry = 3 + 5;
D[1] = 7 < P[1] + carry = 5 + 4;
D[2] = 4 < P[2] + carry = 3 + 2;
D[3] = 8 < P[3] + carry = 8 + 1;
D[4] = 4 <= P[4] + carry = 3 + 1; // now next i = 5 is the same as the starting point ie index 5.
So the starting point is index=5;


Total time complexity: O(n)

- Nascent January 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Of course, assuming that 1 unit of petrol covers 1 unit of distance.

- Thon January 26, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This is n2 complexity. Not n.

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

using this sort of circular queue will make the worst case comparisons as 2*n, ie. when the last value is the only solution, this is still in the order of O(n)

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

this is just a slightly different version of largest sum problem

- zyfo2 January 28, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Hi

I have the same solution as people are suggesting above. But as I had maximum sum sub sequence problem in my homework I would like to write down the logic. So the first point to note is that you can go only from P(i) to P(i+1). So i think taking a circular queue or a list would be wrong. Now you have two arrays, create a third array say arr

where arr[i]=P[i]-D[i];
And now follow this
For every element, find the OPT(i)=max{arr(i),arr(i)+OPT(i-1)}
And base case is OPT(i<0)=0 .
We fill the array from left to right, and the max value in the array would mark the beginning of the journey and where the OPT goes 0, that would mark the end. So the run time is 2n.

- north_remembers January 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

What does it mean? We are supposed to sort the stations list or we have to keep the original sorting and only find a starting point?

In the latter case we'd assume that this list is a cirtular one (a ring), that is the last element's X is the distance from the first station.

- Thon January 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

No sorting required, need to find the starting station from where we can complete the trip to each station in order

- ravigupt January 26, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can we know that how much distance will the vehicle cover in for a given amount of gas? If this becomes known, maybe we can think of trying something like a knapsack kind of optimization strategy here.
But again as you said that sorting is not required, a knapsack problem's solution doesn't stand a chance here.

- Learner January 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

There are few other unknowns that can be discussed.
1) Does the vehicle's fuel tank has enough capacity that if it is full, then it can run between any two stations?
2) If after filling the fuel in the tank, can the excess fuel be carried along? Or the vehicle's fuel tank capacity becomes an upper limit of fuel?

- Learner January 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I was told to make any assumption about fuel tank capacity, the interviewer wanted me to solve the simplest version of this, as this was an initial round of discussion

- ravigupt January 27, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

My solution (1 unit petrol = 1 unit distance). O(n)

public int find(int[] petrols,int[] distances) {
		int[] diff = new int[2*petrols.length];
		for(int i=0;i<petrols.length;i++) { 
			diff[petrols.length+i] = diff[i]  = petrols[i] - distances[i];
			
		}
		boolean[] notOrigin = new boolean[diff.length];
		
		for(int i=0;i<petrols.length;i++) {
			if(notOrigin[i]) continue;
			int sum = 0;			
			for(int j=i;j<i+petrols.length;j++){
				sum+=diff[j];
				if(sum<0) {
					for(int k=i;k<=j;k++) notOrigin[k] = true;
					break;
				}
			}
		}
		
		for(int i=0;i<petrols.length;i++)
			if(!notOrigin[i]) return i;
		return -1;
	}

- MarcoF January 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

i think instead of using continue, we can to do following way for better performance

static int find(int []p,int []d)
{ int diff[]=new int[2*p.length];
for(int i=0;i<p.length;i++ )
{ diff[i]=diff[p.length+i]=p[i]-d[i];

}
for (int j = 0; j < p.length; j++)
{
int sum= 0;
int k ;
for ( k = j; k < j+p.length; k++)
{
sum =sum+diff[k];
if(sum<0){
j=k;
break;
}
}
if(k==j+p.length){return j;}
}
return -1;
}

tell me if it is wrong

- newbie February 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

sorry alreaddy enhanced my bad

- newbie February 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Enhanced version.

public int find(int[] petrols,int[] distances) {
		int[] diff = new int[2*petrols.length];
		for(int i=0;i<petrols.length;i++) { 
			diff[petrols.length+i] = diff[i]  = petrols[i] - distances[i];
			
		}
		
		for(int i=0;i<petrols.length;i++) {
			boolean notOrigin = false;
			int sum = 0;			
			for(int j=i;j<i+petrols.length;j++){
				sum+=diff[j];
				if(sum<0) {
					notOrigin = true;
					i=j;
					break;
				}
			}
			if(!notOrigin) return i;
		}
		return -1;
	}

- MarcoF January 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

O(n) solution:

// first - distance, second - petrol
typedef std::pair<int, int> Station;
typedef vector<Station> PetrolStations;

int GetStartStationIdx(PetrolStations stations)
{
	int result = stations.size() - 1;

	int petrol = 0;
	for(int idx = stations.size() - 2;idx>=0;--idx)
	{
		if ( petrol>0 )
			petrol = 0;
		const Station& station = stations[idx];
		petrol += (station.second - station.first);
		if ( petrol>=0 )
			result = idx;
	}

	petrol = 0;
	for(int i = 0;i<stations.size();++i)
	{
		PetrolStations::size_type idx = (result + i)%stations.size();
		const Station& station = stations[idx];
		petrol += (station.second - station.first);
		if ( petrol<0 )
		{
			result = -1;
			break;
		}
	}

	return result;
}

- Perfect.Hash January 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Not working for

stations.push_back(Station(20, 2));
	stations.push_back(Station(3, 2));
	stations.push_back(Station(3, 6));
	stations.push_back(Station(3, 2));
	stations.push_back(Station(3, 1));
	stations.push_back(Station(4, 4));

and for

stations.push_back(Station(1,0));
	stations.push_back(Station(1,1));
	stations.push_back(Station(1,0));
	stations.push_back(Station(9,13));

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

Hum. It works for both cases, in 1st case it returned 2, and in the 2nd case -1.

- Perfect.Hash January 27, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I assume you have to touch every station, so starting from P(N-1) requires to move circurarly to P(0) where N is the number of stations. In that case first case is -1 and second is 3.

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

Aha, you're right. Looks like I misunderstood the question. The solution should be OK now )

- Perfect.Hash January 27, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

My O(n) solution. I think this works, though the proof is a little tricky.

Instead of worrying about distance and petrol, let's combine them into a single value "surplus", where surplus[i]=petrol[i]-distance[i]. This tells us how much extra (or less) petrol we have left over after moving to the next station.

Say we start from Station [headpt]. If sum(surplus[headpt]...surplus[tailpt])<0 for some Station [tailpt], then Station [headpt] cannot be the first station in the path (since we ran out of petrol before we got to the end). In which case, we take Station[headpt+1] to be our new starting point.

But here's the sneaky part: we don't actually need to sum all the way from the start of the path again! We can remove the surplus of Station[headpt] and continue from where [tailpt] left off. If the sum is still<0, we continue to discard the first station in the path until our sum is >=0.

Why does this work?

If we were to graph the cumulative surplus after each station we visited, the final station (where the total becomes negative) is the lowest point. Removing stations from the front of the path has the effect of shifting the remainder of the graph up or down. No matter what, the last point is always the lowest. Therefore if we delete stations from the front until the cumulative sum is >=0, we can guarantee that all subpaths starting from that station up to [tailpt] have positive sums.

If [tailpt] manages to reach [headpt-1], then we have found a positive path.
Since [headpt] circles through the list of stations at most once, and [tailpt] at most twice, this is O(n).

The code...

//return index of starting station.
public static int findPath(int[] petrol, int[]distance){
	//assume petrol[i]=petrol @ Station [i]
	//assume distance=distance from Station [i] to [i+1]%N
	int N=petrol.length;
	int[] surplus=new int[N];//how much surplus petrol we obtain traveling [i]->[i+1].
	for (int i=0;i<N;i++){
		surplus[i]=petrol[i]-distance[i];
	}
	int cumsum=0;//sum of surpluses
	int headpt=0;
	int tailpt=0;
	while(headpt!=N){
		cumsum+=surplus[tailpt];
		while(cumsum<0){
			//delete petrol station at headpt from path. Must stop when headpt==tailpt.
			cumsum-=surplus[headpt];
			headpt++;
		}
		tailpt++;
		tailpt%=N;
		if(tailpt==(headpt-1+N)%N)//have reached last station.
			return headpt;
	}
	return -1; //couldn't find anything
}

- larkasc January 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Ha just realised you can do one better. If station[tailpt] is the lowest point on the graph, none of the other subpaths up to station [tailpt] will be able to give cumsum>=0.

Therefore you can remove the "while(cumsum<0)" loop and replace it with

if(cumsum<0)
headpt=tailpt+1;

- larkasc January 28, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

For each station consider the difference between petrol and distance. Let's assign to each station the letter P if this difference is positive or N otherwise. Starting from station i-nt find the cumulative sum cs for each station to the j-th untill cs<0. At this point you can say that i-th is not the start. But (trick) you can exclude all stations in range [i,j]. In fact, if you have (for instance) the sequence P,N,P,P,N,P,N and only after last N you have cs<0, you can conclude it will be negative also if you start from every P in the sequence (because sum is still positive after every N but the last). Now you can scan just once the sequence and find (if any) the starting point. Check my algo above.

- MarcoF January 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

it's still O(n^2)

- xYz January 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

No, I think it is O(n). You have to add every point to the cumulative sum just once.

- MarcoF January 28, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

find the max of x-d. that is starting point?

- anil January 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Not always. What if you cannot cover all the path with available petrol, i.e. sum(all distances)>sum(all petrols)?

- MarcoF January 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

It might be solved using the maxsum subarray algorithm, the element of the values are (petrol amount - distance). So, the start station must be the start element of the max sum subarray.

- Shu January 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Assuming you have to touch all stations (circularly) the cumulative sum (petrol amount - distance) is a constant and never changes.

- MarcoF January 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

ok.
so take the x-d for all (O(n))
then find the largest -ve value from above.
go back from that point and see when we can pass the -ve value (by adding the x-d for those nodes).
When we pass that node will be starting point

- anil January 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

boolean checkedOnce=false;
int coveredPlaces=0;
int pos=0;
int carry=0;
int n=5;
int[] D={6,6,4,2,6};
int[] P={7,5,3,1,8}

while(covered!=(n-1))
{

if(pos==0 && covered==0 && checkedOnce)
{ break;}
else
{checkedOnce=true;)

if(D[pos]<=(P[pos]+carry))
{
covererd++;
if(pos==(n-1))
{
pos=0;
}
carry=(P[pos]+carry-D[pos]);
}
else
{
covered=0;
carry=0;
}
}

if(covered==(n-1)){

if(pos==(n-1)){
out(0);
}
else
{
out(pos+1);
}
}

- aseem February 05, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

find minimum subarray of the array of values (X[i] - D[i]). Then the starting point of the journey would be next to the end of that subarray.

Assumed it is a circular list and such a journey is possible based on the sum of distance and sum petrol.

- Vasanth February 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <vector>
#include <iostream>

/*
 Given a list of n gas station of form P(D,X) where D is the distance from this station to next station and X
 is the amount of petrol available at this station, identify the starting station from where you can complete
 journey to each station in order from 1.....N. You can only go in one direction i.e from P(i) to P(i+1) 
*/

int main(int argc, char **argv)
{
/*
  std::vector<std::pair<int, int>> P = {
    { 4, 3 }, 
    { 7, 5 },
    { 1, 6 },
    { 4, 3 },
    { 8, 8 },
    { 4, 3 },
  };
*/

/*
  std::vector<std::pair<int, int>> P = {
    { 20, 2 }, 
    {  3, 2 },
    {  3, 6 },
    {  3, 2 },
    {  3, 1 },
    {  4, 4 },
  };
*/

  std::vector<std::pair<int, int>> P = {
    { 1,  0 }, 
    { 1,  1 },
    { 1,  0 },
    { 9, 13 },
  };

  size_t count = P.size();
  std::pair<int, int> candidate(-1, -1);
  for (auto i = 0; i < (P.size() * 2) - 1; ++i) {
    if (i < P.size()) {
      if (P[i].first <= P[i].second && candidate.second < 0) {
        candidate = std::pair<int, int>(i, 0);
        count = P.size();
      }
    }

    if (candidate.second >= 0) {
      candidate.second += (P[i % P.size()].second - P[i % P.size()].first);
      --count;
    }

    if (!count) {
      std::cout << candidate.first <<std::endl;
      break;
    }
  }

  return 0;
}

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

A valid starting point would satisfy the following 2 properties:
Assuming P(D,X) = {(d1, x1), (d2, x2),...(dr, xr),...(dn, xn)};
Let valid starting station is, P(dr, xr), then:

1. dr < xr
2. for all i,  r < i < n:
	Σdi  < Σxi

Solution would be O(n).

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

corrected bounds for summation:

for all i,  r < i < n:
	Σdt (t=r to i)  < Σxt (t=r to i)

- theGhost September 09, 2013 | Flag


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