Google Interview Question for Software Engineer Interns


Country: United States
Interview Type: Phone Interview




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

My algorithm is a slight tweak of the algorithm which finds all pairs that sum up to certain value. Algorithm sorts the array first and initialize first = 0, last = last element. Then iteratively it examines the array. Here is the code:

def findPairsLessThen(a, s):
	if len(a) < 2:
		return None
	a.sort()
	first = 0
	last = len(a) -1
	while first < last:
		if a[first] + a[last] > s:
			last -= 1
		else:
			for i in range(first + 1, last + 1):
				print a[first] + a[i], first, i
			first += 1

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

Approach:
1). QuickSort the list
2). Find out the max position (say p) where it's just less than or equal to K
3). Loop through the list starting at (P) backward. Find the difference between the current indexed number and K (say q). Use binary search to find the max (say t) position of q. Then combine everything below t and p to add to the answer set.

Sample data:
List: 1, 3, 5, 9, 20, 28, 30, 37, 60, 100
K: 50

So, the max position of p is at 37. Now, we loop through the list backward, 37 +30 <= 50? No. 37 + 28 <= 50? No. 37 + 20 <= 50? No. 37 + 9 <= 50? Yes. Then combine everything below 9 and 37.

pseudo code:

quicksort(list)

int p = binarysearch_max_position(k, list.length)
// p is the max position where it's just less than or equal to k in the list

for (i=p; i>=0; i--) [

x = list(i);

d = k - x;
// d is the difference in between k and x

j = binarysearch_max_position_helper(d,i)
// find the max position where j can exist
// since everything below j is less than j
// that it means position [0 to j] can be
// added to x and still be less than or equal
// to k

(if j != -1) {
all_combination_generator(j,i);
}

}

private void all_combination_generator(int i, int j) {

for (int x = i; x>=0; x--) {
answerset.add(j,list[x]);

}
}

Is this o(nlogn)?

- alex February 05, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I don't get it. What do you mean by "combine everything below 9 and 37" in the example? You mean (9, 37), (5, 37)... ? But (20, 28) also is an answer.

- Mark February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

And why do you need quicksort if you want numbers less than K? It needs just one pass of the array. Pick the number if it is less than or equal to K. Otherwise, not.
It is O(n).

- Mark February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sorry that my statement caused some confusion. When I say "combine everything below 9 and 37", I should have said combine (everything below 9) and 37. In that example, 50 - 37 => 13. In the sorted array, we can find that 9 is max number below 13. With that, we know for sure that everything below 9 can be combined with 37 and be the answer, and everything above 9 isn't an answer with 37. The logic is to do a binary search to determine which set can be combined with this number.

As for your second question, the quicksort is just to put the list into a sorted order. For the second part, sorry that I am not sure if I get your solution. It sounds like you are just picking one number, but the question is asking for a pair of number. If you don't sort it, you can not do binary search. Again, apologize if I don't quick get your suggestion.

Hope this helps.

- Alex February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I just re-read my solution. Just to clarify (which I think that's what your question is at)

1). QuickSort the list
2). Find out the max position (say p) where it's just less than or equal to K

This is done so that we know where we should begin the loop backward.

In my example. (We need #1 to do this sorting because the question doesn't mention that the list is sorted)

List: 1, 3, 5, 9, 20, 28, 30, 37, 60, 100
K: 50

#2 is to find out the index at 37. With that, we can eliminate whatever that's on the right hand side of 37 since they are bigger than K by itself.

Actually, this is a good point as I typed it. The question didn't say that the number is all positive. My solution would work with assumption of all integers in the list being positive, but if it can be negative, then it's more complicated...

- Alex February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The question said it is a list, how can we quick sort a list? And how to random access the list?

- Huo February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Ha, good catch. Not sure if the interviewer's question was meant for linked list, arraylist or just a generic term for a loose data structure. If we don't have space constraint and this is really a "list", we can first convert this list to an array first which is o(n) and it doesn't affect the overall running time. I guess it's one of those assumptions can be cleared in the interview (same goes for if these integers are all positive).

- Alex February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

If we can put the list into array, it is just a similar question to 2sum, is it?

- Huo February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

If Sample data:
List: 1, 3, 5, 9, 20, 28, 30, 37, 45, 60, 100
K: 50
Then what will be the max position of p?

- Ripon February 07, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Ripon, the P would be at index of 45 since that's the max number in the list less than K (50).

- Alex February 08, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Is there negative integers in the input?

- Jeremy February 08, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Jeremy, I think the question didn't specify this, so it's definitely one of the assumptions that should be asked and clarified. It would be an added on requirement which can be asked once you have a solution for positive number. If negatives are allowed, then it's more complicated problem (with constraint of doing less than O(n^2))

- Alex February 08, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I came up with same solution as @alex.
For negative numbers just change the pointer to be the first value <= k-min value in list.

Say k is 5, Sorted list: -2, -1, 2, 4, 6, 7, 8
Start pointer at first value <= (5--2=7) , and generate pairs moving left starting at second pointer (-1)
so (7, -2),
(6,-1)
and so on

- Dave February 11, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

this method misses the pair (20,30)

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

Instead of carrying binary search every time (in a list where we cant jump to a node directly) and reverse traversing the sorted list, you can :
a. Sort list
b. Say first node is min. Find maximum node, max,. s.t. min + max <= K. Push each and every node including it on to a stack.
c. start traversing from first node. Say cur val is cur and it is the ath node (starting from 0th as the first node). Pop stack until cur + popped value <= K. pairCount += no. of stacked element - a (No. of pairs cur makes that are <= K).

- srikantaggarwal February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

1) Scan all elements and store all elements <= k in an array A O(n)
2) Sort this array. Let the total elements be e O(e*loge) in descending order
3) For i from 1 to e/2
d = k-A[i]
Do a binary search in this array to find the position of d. Output pairs A[i] and all A[j<=d]

Total complexity O(n) + O(e*loge)

- kr.neerav February 06, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

very neat solution.

- tomnebula February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

doesn't print out pairs A[i] and all A[j<=d] O(d)?
therefore your last step would be O(e*d)

- yyl February 08, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Im sorry typo above. I mean O(e*L), suppose L to the length of A[j<=d]

- yyl February 08, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

What if there can be NEGATIVE INTEGERS?

- Jeremy February 08, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

People should realize that this question has a lower bound of O(n^2). Imagine the list {1, 2, 3, 4, 5, 6} and the number 5000 as k. In this case all of the numbers can be combined so we need to print 1 + 2 + ... + n - 1 = n * (n + 1) / 2 ( = O(n^2) )combinations.

- kennelcrash November 15, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

You mean it is a list? If it is a list, you can't quicksort it, don't you? Only mergesort may apply. But still it is not random access. So if it is a list, either use map(this will be O(n),O(n)) or use loop(O(n^2),O(1))

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

how about a modified version of a count sort where n is the number of records, and a is the array, if we assume that 0 <= a[0:n] <= m, we allocate a new array b of size m that stores the sorted array, and a Hash Set of capacity m that stores an ADT called Solution,

The Solution ADT is a pair of integers, a and b, the idea is that a + b <= k, and more solutions can be from the fact that all Solution(a, 0...b) and Solution(0...b) are also solutions

At the end we will have a Set of Solutions

pseudocode:

for i in 0...n {
   b[a[i]] += 1;
   if(b[a[i]]) > 0 {
      solutions.add(new Solution(b[a[i]], k - b[a[i]]));
   }
}

solutions = expandSolutions(solutions);

space complexity would be O(2m)

time complexity would be O(n + expandSolutions) = O(n + k^2)


if k is <<< n then the whole thing could run in O(n)

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

Will you let me know what exactly the array j is containing.. and what are you trying to decrease with j--?

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

I think it can be done in O(n^2)

Iterate through the array and keep on creating the set with that number in case its lesser than k and also check that number against all the existing sets to see if that satisfies the criteria.

- Caduc3us February 12, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can we use hashmap here?
like we can scan the list for numbers less than or equal to k and store it in hashmap (n, k-n). After putting all the elements we can just scan through the hash map and for each key, we will just have to check if the value is present in the key set. If yes then consider that to be the pair and continue with other keys.

- ks February 20, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include<iostream>
#include<algorithm>

using namespace std;

int main()
{

int a[] = {3, 1, 4, 2, 9, 10, 33, 42, 2, 0, 6};
int N = sizeof(a) / sizeof(*a);
sort(a, a + N);
for(int x=0 ;x<N;x++)
{

cout<< a[x]<<" , ";
}
cout<<endl;


int K = 12;
int i = 0;
int *t = std::upper_bound(a, a + N, K - a[0]);
int j = t-a-1;
cout<< *t << " "<< *a<<" "<<j<<" "<<endl;

while (i < j) {
for (int k = i + 1; k <= j; k++)
cout << "(" << a[i] << ", " <<a[k] << ") ";
i++;
while (a[i] + a[j] > K && i < j) {
j--;
}
}system("pause"); }

- Babu lion March 05, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I would approach it that way:

1. Sort the list in ascending order with nLogn (e.g. QuickSort)
2. Allocate two indexes––smaller and bigger (at the beginning smaller points to the first element of the list and bigger points at the last element)
3. Make a while loop with a termination condition smaller != bigger. Now compute the sum list(smaller)+list(bigger). If it is greater than k, there's no need to find the sums of the rest elements with bigger, so decrement bigger by 1 and continue to the beginning of the loop.

Else if the sum is smaller or equal to k, print out smaller paired with each of the rest of the elements. Increment smaller by 1 and continue to the beginning of the loop.

- dmtrkzkv October 20, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I have a simple solution in O(nlogn). First sort the list of numbers. Then iterating from starting (i=1 to n). Do a modified binary search for the remaining n-i+1 elements with l=i ,r=n and find the element of index with floor (k-a[i]). No_of_pairs+= g-i+1.

Please comment if there's any error with the logic.

- kp January 05, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Solution with time O(n) and space O(k)

Make an array arr[k]
Scan the list and increment index at position arr[i]
Have a pointer i = a[0] and j = a[k]
Find min(a[i], a[j])
Increment i and decrement j.

- srezaie@calpoly.edu February 06, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Why do we need O(n^2log(n)) to solve this ??

Even the brute force solution, where we simply produce all the pairs and check if their sum is <k or not is O(n^2)

I don't believe that we can solve this problem in anything less than O(n^2) because in worst case sum of elements for all the pairs will be <k and there are O(n^2) pairs.

- Aritra February 05, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can you shed some insight about the steps other than just comparing the elements?

- hirajhil February 05, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

sample code test.cpp

#include <stdio.h>
#define SIZE 5000000

int main() {
	int arr[SIZE] = {.....} //initialization of array
	int k = ..; //something

	for(int i=0; i<SIZE - 1; i++)
		for(int j=i+1; j<SIZE; j++)
			if((arr[i] + arr[j]) <= k)
				printf("(%d,%d)\n", arr[i], arr[j]);
	}

- Aritra February 05, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

int a[] = {3, 1, 4, 2, 9, 10, 33, 42, 2, 0, 6};
    int N = sizeof(a) / sizeof(*a);
    
    sort(a, a + N);
    int K = 12;
    int i = 0;
    int *t = std::upper_bound(a, a + N, K - a[0]);
    int j = t - a - 1;

    while (i < j) {
        for (int k = i + 1; k <= j; k++) 
            cout << "(" << a[i] << ", " <<a[k] << ") ";
        i++;
        while (a[i] + a[j] > K && i < j) {
            j--;
        }
    }

- Westlake February 06, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

My algorithm is as follows:
First of all, I assume the integers in the array and K are nonnegative numbers.
I use a hash table to store numbers as a key and the count of that number as a value.

PseudoCode

for(Integer i : arr) {
	for(int j=K-i; K>=i &&  j>=0; j--) {
		if(HashMap.containsKey(j))
			sum += HashMap.get(j); // You can print out the pairs here. (i, j) which sums less than or equal to K. and its number is HashMap.get(j) for one i.
	}
	if(HashMap.containsKey(i))
		HashMap.put(i, HashMap.get(i)+1);
	else HashMap.put(i, 1);
}

From the two loops, I think the complexity is O(n * K).

- Mark February 06, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
Comment hidden because of low score. Click to expand.
0
of 0 votes

it is smart to scan from both sides. but I think this may miss some paris when there are duplicate elements.
e.g. A = [0, 0, 1, 1, 1] and K = 3

- arthur February 26, 2014 | 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