Google Interview Question for Software Engineer / Developers


Country: United States




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

Modified Kadane's algo will be O(N)

- mindless monk November 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
3
of 3 votes

I think in this case it's about a sub-array that doesn't have to be contingous.

- joe kidd November 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Well then the question is re-defining what "sub-array" means. I do not think any interviewer would want to do that.

- mindless monk November 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Yeah, the subarray is subarray :) Vote up for you.

- joe kidd November 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

yeah seems the correct way to solve this provided interviewer asked only for subarray.

Given array of pairs is from 0...N-1.
Pair has first and second elements, where first indicates the order and second indicates element value, which needs to be added for sum.

int max_ending_here, max_ending_so_far = 0;
int begin, end = 0;
int begin_temp = begin;

for(int i = 1; i< pairsArray.length; i++)
{
	if(pairsArray[i-1].first < pairsArray[i].first)
	{
		if(max_ending_here < 0)
		{
			max_ending_here = pairsArray[i].second;
			begin_temp = i;
		}
		else
		{
			max_ending_here += pairsArray[i].second;
		}

		if(max_ending_here >= max_ending_so_far)
		{
			max_ending_so_far = max_ending_here;
			begin = begin_temp;
			end = i;
		}
	}
	else
	{	
		max_ending_here = 0;
		begin_temp = i; 
	}
}

This was good question. I guess if the interviewer was to test the thinking , then he must have asked for sub-Array. But if it has been to test whether you can apply different algorithm techniques, then he might have asked for sub-sequence.

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

@ Anonymous:
in input of : <2,3> <4,1> <1,5> <2,6> <3,-12>
on first iteration you will not get sum of 4, you will get sum 1 as you are not taking <2,3> in summation.
Similarily, when encountered with <1,5> u will miss this pair while calculating <2,6>

- SK January 04, 2014 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

Kadane algorithm

def max_sum(seq):
    
    max_sum_= 0
    sum_ = 0
    for i in seq:
        if sum_ + i < 0:
            sum_ = 0
        else:
            sum_ += i
        
        max_sum_ = max(sum_, max_sum_)

    print "Max sum is {0}".format(max_sum_)

Modified for this problem:

def max_sum_sorted(seq_pairs):
    
    max_sum_= 0
    sum_ = 0
    
    # Initialize to the maximum negative integer
    prev_first = -sys.maxint
    
    for pair in seq_pairs:
        # first element has to be sorted
        first, second = pair
        
        if first < prev_first:
            sum_ = 0
    
        if sum_ + second < 0:
            sum_ = 0
        else:
            sum_ += second
    
        max_sum_ = max(sum_, max_sum_)
        prev_first = first

    print "Max sum is {0}".format(max_sum_)

- Messi November 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

This algorithm will give the consecutive sub-array with the two properties. But in a general case where the sub-array needs not to be consecutive, the algorithm will not give the optimal solution.

This problem is a weighted version of the longest increasing subsequence problem. I give a O(n^2) algorithm below:

double max_sum(List pairs){
	pairs = pairs.leftappend(<Integer.MinValue, 0>);
	int n = pairs.length;
	double[][] L = new double[n][n];
	for(int i  = 0; i<n; i++){
		if(pairs[i].a >= pairs[n-1].a){
			L[i][n-1] = Integer.MinValue;
		} else {
			L[i][n-1] = pairs[n-1].b;
		}
	}
	for(int j = n-2; j>= 0;j--){
		for(int i = 0; i<n; i++){
			L[i][j] = L[i][j+1];
			if(pairs[i].a < pairs[j].a){
				if(L[i][j] < L[j][j+1] + pairs[j].b){
					L[i][j] = L[j][j+1] + pairs[j].b;
				}	
			}
		}
	}
	return L[0][1];
}

- ShiguangWang November 19, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

If the subarray is contingous then you can go for Kadan's algorithm suggested by mindless monk. If you need to consider subsequence then dynamic programming approach, as the optimal substructure property is met: you may process the task from left to right, as if A is a solution of size N, and A is optimal it has to be also a part of a solution of B, of size N + 1.

So you should build a helper array M, where

for each i < N
 for each j < i
   if a[i] > a[j] && b[i] + M[j] > M[i] then
    M[i] = b[i] + M[j]

And then for the maximum value of M reconstruct the solution.

- joe kidd November 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

In some cases there is confusion between sub-array and sub-sequence. Here it should be obvious that sub-sequence is intended.

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

O(n) Complexity

public static void max_subsequence(Item[] array){
 	String paths[] = new String[array.length];
 	int sum[] = new int[array.length];
 	int max  = Integer.MIN_VALUE;

 	for(int i = 0; i < array.length; i++){
 		sum[i] = array[i].b; 
 		paths[i] = "<" + array[i].a + "," + array[i].b +"> ,";
 		if(sum[i] > max){
 			max = sum[i];
 		}
 	}
 	for(int i = 1; i < array.length; i++){
 		if( array[i-1].a <= array[i].a && (sum[i-1]+ sum[i])> sum[i]){
			paths[i] = paths[i-1] + paths[i];
			sum[i] = sum[i-1] + sum[i];
			if(max < sum[i]){
				max = sum[i];
			}
		}
	}
	for(int i = 0; i < paths.length; i++){
		if(max == sum[i]){
			System.out.println("["+i+"]"+ " MAX: " + paths[i] + " = " + sum[i]);
		}else{
			System.out.println("["+i+"]"+paths[i] + " = " + sum[i]);
		}
	}
 }

- .·´¯`·.´¯`·.¸¸.·´¯`·.¸><(((º> November 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This clearly cannot work. For one, your maximum subsequence is going to be at most one item long.

- Camillo November 16, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

explain why not.

give some test cases.

I bet, It works

- .·´¯`·.´¯`·.¸¸.·´¯`·.¸><(((º> November 16, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

How much are you willing to bet?

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

I am sorry. I just test it out my code and YES! I HAD a very BAD Bug:
I wrote: sum[i] = array[i-1].b + array[i].b;

when I should use the sum[] values ( which is actually the most importan part of my code:
sum[i] = sum[i-1] + sum[i];
Sorry about that. I've fixed it.
Please send me the bill or the bet I've lost lol
This is a variation of the Kadane's Algorithm

public static void max_subsequence(int sequence[]){
		int MAX = Integer.MIN_VALUE;

		String paths[] = new String[sequence.length];
		int sum[] = new int[sequence.length];
		for(int i = 0; i <sequence.length; i++){
			paths[i] = sequence[i] + ",";
			sum[i] = sequence[i];
			if(sum[i]>MAX){
				MAX = sum[i];
			}
		}
		
		for(int i = 1; i < sequence.length; i++){
			if((sum[i-1] + sum[i]) > sum[i]){
				paths[i] = paths[i-1] + paths[i];
				sum[i] = sum[i-1]+sum[i];
				if(MAX < sum[i]){
					MAX = sum[i];
				}
			}
		}

		for(int i = 0; i < sum.length; i++){
			if(MAX == sum[i]){
				System.out.println("MAX: "+paths[i] + " = " + sum[i]);
			}else{
				System.out.println(paths[i] + " = " + sum[i]);
			}
		}

	}

- .·´¯`·.´¯`·.¸¸.·´¯`·.¸><(((º> November 16, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

INPUT:

max_subsequence(new Item[]{ 
			new Item(1,-2),
			new Item(2,1),
			new Item(3,-3),
			new Item(4,4),
			new Item(5,-1),
			new Item(6,2),
			new Item(7,1),
			new Item(8,-5),
			new Item(9,4)
		});
OUTPUT:

[0]<1,-2> , = -2
[1]<2,1> , = 1
[2]<2,1> ,<3,-3> , = -2
[3]<4,4> , = 4
[4]<4,4> ,<5,-1> , = 3
[5]<4,4> ,<5,-1> ,<6,2> , = 5
[6] MAX: <4,4> ,<5,-1> ,<6,2> ,<7,1> , = 6
[7]<4,4> ,<5,-1> ,<6,2> ,<7,1> ,<8,-5> , = 1
[8]<4,4> ,<5,-1> ,<6,2> ,<7,1> ,<8,-5> ,<9,4> , = 5

INPUT:
max_subsequence(new int[] {-2,1,-3,4,-1,2,1,-5,4});
OUTPUT
[0]-2, = -2
[1]1, = 1
[2]1,-3, = -2
[3]4, = 4
[4]4,-1, = 3
[5]4,-1,2, = 5
[6] MAX: 4,-1,2,1, = 6
[7]4,-1,2,1,-5, = 1
[8]4,-1,2,1,-5,4, = 5

- .·´¯`·.´¯`·.¸¸.·´¯`·.¸><(((º> November 16, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

axel.david.velazquez following in Ajeet's footsteps

- *regex* November 16, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

First sort the array based on the first element and save them in an other array call c.
Then we can reduce the problem to find the LCS ( longest Common Subsequence ) problem. Let bi, be the weight whether we choose ai or not, instead of length weight is important here. Using dynamic programming the running time is O(N^2)

- HoneyBall November 18, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Why would you think that the Kadane's Algorithm is the solution? Read the original question again slowly: "the 1st element in the pairs are in increasing order and the sum of 2nd element of the pairs in the sub-array is maximum possible" The 2nd element of the pairs is the "maximum possible"... Given the input pairs:

max_subsequence(new Item[]{ 
			new Item(1,-2),
			new Item(2,1),
			new Item(3,-3),
			new Item(4,4),
			new Item(5,-1),
			new Item(6,2),
			new Item(7,1),
			new Item(8,-5),
			new Item(9,4)
		});

integer 6 is not the max possible as the algorithm is determining, 12 is the max possible integer of the 2nd element. First it's assumed that the pairs are sorted based on their first element. Second, remove all pairs where the 2nd element is negative. You end up with this list of pairs:

Item(2,1),
Item(4,4),
Item(6,2),
Item(7,1),
Item(9,4)

The first elements are in increasing order, and the sum of the second elements are the maximum positive integer. If there happen to be additional criteria that there cannot be gaps in the first elements order then that should be noted in the question, but the question just says "increasing order". Are they not increasing order?

- Perry Nally November 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Additionally, If the "increasing order" should rule out the fact that the first element of any two pairs is the same number {2,3}, {2,5}, then you would always take the pair with the larger second element.

- Perry Nally November 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

double getMax(vector< pair<double, double> > v) {
	assert(v.size() > 0);
	int bleft=0, bright=0;
	int tmp_left = 0;
	double bv=v[0].second;
	double cv = bv;
	for (int i = 1; i < v.size(); i++) {
		if (cv < 0 || v[i].first < v[i-1].first) {
			cv = v[i].second;
			tmp_left = i;
		} else {
			cv += v[i].second;	
		}
		if (bv < cv) {
			bleft = tmp_left;
			bright = i;
			bv = cv;
		}
	}
	return bv;
}

- jarc November 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Simple in Java

public class GetRequiredRangeInPairArray {

	private static class IntPair {

		int first_;
		int second_;
		IntPair (int f, int s){
			first_ = f; second_ = s;
		}
		int first() { return first_; }
		int second() { return second_; }
		
		@Override
		public String toString() {
			return "["+first()+"," +second()+"]";
		}
	}


	static class Range extends IntPair {
		Range(int s, int e){ super(s,e); }
		int start() { return (int) super.first(); }
		int end () { return (int) super.second(); }

	}
	
	
	// the range includes start but not the end
	public static Range getRequiredSubArray(IntPair [] arr){
		int n = arr.length;
		if(n < 1) return new Range(0,1);
		if(n == 1) return new Range(0,1);

		int maxSum = Integer.MIN_VALUE;
		int maxStart = 0;
		int maxEnd = 0;

		int start = 0;
		int sum = 0;
		int prevFirst = Integer.MIN_VALUE;	
		for(int i = 0;  i < n ; i++){
			IntPair r = arr[i];
			if(sum <=0 || prevFirst >= r.first()){
				start  = i;	
				sum = 0;
			}  

			sum += r.second();

			if(sum > maxSum){
				
				maxSum  = sum;
				maxStart = start;
				maxEnd  = i;
			}
			prevFirst = r.first();

		}


		return new Range(maxStart, maxEnd+1);


	}


	public static void main(String[] args) {
		IntPair [] arr1 = {
				new IntPair(2,Integer.MIN_VALUE),
				new IntPair(1,10),
				new IntPair(3,-5),
				new IntPair(5,-7),
				new IntPair(1,10),
				new IntPair(3,-5),
				new IntPair(5,7),
				new IntPair(5,7),
		};
		System.out.println(getRequiredSubArray(arr1));
	}
	
}

- konst June 03, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Modified Kadane's algorithm

public class KadaneForPair {

	private class Pair {
		public int a;
		public int b;

		public Pair(int a, int b) {
			this.a = a;
			this.b = b;
		}
	}

	public Pair[] findMaxSubArray(Pair[] input) {
		int start = 0;
		int maxSum = input[0].b;
		int bestSum = input[0].b;

		int bestStart = 0;
		int bestEnd = 0;

		for (int i = 1; i < input.length; i++) {

			/*
			 * we reposition start index only when the continuity of first a
			 * breaks.
			 */
			if (input[i].a < input[i - 1].a) {
				start = i;
				maxSum = input[i].b;
			} else {
				maxSum += input[i].b;
			}

			if (maxSum > bestSum) {
				bestSum = maxSum;
				bestStart = start;
				bestEnd = i;
			}
		}
		System.out.println("bestStart: " + bestStart + " bestEnd: " + bestEnd);
		Pair[] out = new Pair[bestEnd - bestStart + 1];
		System.arraycopy(input, bestStart, out, 0, bestEnd - bestStart + 1);
		return out;
	}

	public static void main(String args[]) {
		KadaneForPair test = new KadaneForPair();
		Pair[] input = new Pair[5];
		input[0] = test.new Pair(10, 2);
		input[1] = test.new Pair(2, 10);
		input[2] = test.new Pair(3, 2);
		input[3] = test.new Pair(5, 87);
		input[4] = test.new Pair(-1, 10);
		Pair[] out = test.findMaxSubArray(input);
		System.out.println("input:");
		display(input);
		System.out.println("output: ");
		display(out);
	}

	private static void display(Pair[] out) {
		for(int i =0;i<out.length;i++){
			System.out.print("(" + out[i].a+ ", " + out[i].b + ") ");
		}
		System.out.println();
	}
}

- sukheshmg November 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The algorithm fails at input: {<-1, -1> , <-1, -1>, <-1, -1>}

- jarc November 19, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

can you please explain?

this is the output i got

bestStart: 0 bestEnd: 0
input:
(-1, -1) (-1, -1) (-1, -1)
output:
(-1, -1)

your input has all negative elements. if you sum up any two of them you get a lower value than either of them. so, your output array must have a single element i.e. the element that has the highest 2nd element in the pair.

- sukheshmg November 19, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sorry, I was wrong. But how about this input :
(1, 2) (2, -100) (3, 3) (4, 4) (5,5)

Your output will be : 2.
But the best should be : 3 + 4 + 5. right?

Note that 'start' in your code will always be 0.

- jarc November 19, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

thanks for pointing it out. my assumption that we don't need a repositioning of start as long as there is ascending order was wrong. if the sum goes negative, we need to reposition the start.

here is the edited code:

public class KadaneForPair {

	private class Pair {
		public int a;
		public int b;

		public Pair(int a, int b) {
			this.a = a;
			this.b = b;
		}
	}

	public Pair[] findMaxSubArray(Pair[] input) {
		int start = 0;
		int maxSum = input[0].b;
		int bestSum = input[0].b;

		int bestStart = 0;
		int bestEnd = 0;

		for (int i = 1; i < input.length; i++) {

			/*
			 * we reposition start index when the sum goes negative or if the
			 * ascending quality breaks
			 */
			if (input[i].a < input[i - 1].a || input[i].b + maxSum < 0) {
				// change this to <= if you want the longest possible subarray
				if (input[i].b + maxSum < 0) {
					start = i + 1;
					maxSum = 0;
					i++;
				} else {
					start = i;
					maxSum = input[i].b;
				}
			} else {
				maxSum += input[i].b;
			}

			if (maxSum > bestSum) {
				bestSum = maxSum;
				bestStart = start;
				bestEnd = i;
			}
		}
		System.out.println("bestStart: " + bestStart + " bestEnd: " + bestEnd);
		Pair[] out = new Pair[bestEnd - bestStart + 1];
		System.arraycopy(input, bestStart, out, 0, bestEnd - bestStart + 1);
		return out;
	}

	public static void main(String args[]) {
		KadaneForPair test = new KadaneForPair();
		Pair[] input = new Pair[5];
		input[0] = test.new Pair(1, 2);
		input[1] = test.new Pair(2, -100);
		input[2] = test.new Pair(3, 3);
		input[3] = test.new Pair(4, 4);
		input[4] = test.new Pair(5, 5);
		Pair[] out = test.findMaxSubArray(input);
		System.out.println("input:");
		display(input);
		System.out.println("output: ");
		display(out);

		Pair[] input2 = new Pair[3];
		input2[0] = test.new Pair(-1, -3);
		input2[1] = test.new Pair(-1, -2);
		input2[2] = test.new Pair(-1, -1);
		out = test.findMaxSubArray(input2);
		System.out.println("input:");
		display(input2);
		System.out.println("output: ");
		display(out);
	}

	private static void display(Pair[] out) {
		for (int i = 0; i < out.length; i++) {
			System.out.print("(" + out[i].a + ", " + out[i].b + ") ");
		}
		System.out.println();
	}
}

- sukheshmg November 19, 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