Google Interview Question for Software Engineer / Developers






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

How about using max heap
1. take out the first K number, reverse it and save it in a heap H;
2. i=1 at first, compare A[i]+A[i+1] with the root of heap H[0], if lesser then abstract the maximum and insert the sum. loop until A[i]+A[i+1]>H[0].
3. i=1 at first,compare A[i]+A[i+1]+A[i+2] with the root of heap H[0], if lesser then abstract the maximum and insert the sum. loop until A[i]+A[i+1]+A[i+2]>H[0].
the first step cost O(K) while second and third step take O(KlogK).

- yangjian0219 April 19, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

int j=n-1, t = n-2, x = n-1, y = n-2, z = n-3;
    for(int i=n-1; i >= 1 && ind ;i--){

       // find pairs larger than the single element (i)
       for( ; j >= 1 && ind ;j--){
         for(; t>=0 && A[j]+A[t]>A[i];t--){

        // find triples larger than the pair (j,t)
           for(; x >= 2 && ind ;x--){
              for(; y>=1 && ind;y--){
                 for(; z>=0 && ind && A[x]+A[y]+A[z] > A[j]+ A[t] ;z--){
                   B[--ind] = A[x]+A[y]+A[z];
                 }
              }
           }
           
           // all triples larger than (j,t) are printed
           B[--ind] = A[j]+A[t];
    }
    // all pairs larger than (i) are printed
    B[--ind] = A[i];
}

It is O(k) because the loops continue from where they left...

- Anonymous April 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

the inner loop indices should be reset when the outer loop index is decremented, something like
for(; y>=1 && ind;y--,z=n-2)...
and
for(; x >= 2 && ind ;x--, y=n-1){

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

If you dare to take the challenge, upload your code to ideone.com. I'm pretty sure there are so many catches in your funky code.
IMO, Google is not that much crazy to ask about 6-level loop problem in an interview !

- anon April 08, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

a sample output:
array [] = {1,2,3,4,5}
number of smallest K = 16

1 = 1
2 = 2
3 = 1 + 2
3 = 3
4 = 1 + 3
4 = 4
5 = 2 + 3
5 = 1 + 4
5 = 5
6 = 1 + 2 + 3
6 = 1 + 5
6 = 2 + 4
7 = 1 + 2 + 4
7 = 2 + 5
7 = 3 + 4
8 = 1 + 3 + 4

- anon April 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

consider the example for K = 15 (sum up to 7). there are other combination to make the sum = 8

- anon April 08, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

Here's my solution using min heap that takes O(K log K) : ideone.com/BNIv7

Heap is initialized with smallest sum of 1, 2 and 3 elements, i.e. A[0], A[0]+A[1] and A[0]+A[1]+A[2]. Each sum keeps information of number of elements, and the indices of the elements. When the min sum in heap has one element, for example A[i], next element A[i+1] is inserted in Heap. For sum with 2 and 3 elements, the combinations of element need to be generated in a unique manner such that no two sum consisting of same indices can ever be generated. This is the hardest part of the solution. Try to work with previous posted example : {1,2,3,4,5} and K = 25.

I used verification to test my code with random input for N = 10, 20, 30, 40 and 50. Max. value of K was used to verify all possible combinations of sum. Hence for N = 50, K <= 50C3 + 50C2 + 50 = 20875. If you want to run with own input, please comment out line # 11.

- buried.shopno April 09, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

assumption in my solution is that all numbers are positive. waiting to see some better solution for general case.

- buried.shopno April 09, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 votes

Your idea looks almost right. Here is how I make your idea working correctly:

1) When the min sum in heap has one element, for example A[i], next element A[i+1] is inserted in Heap.

2) For sum with 2, the indexes are i and j,
we need to compare
a) when j==i+1, the next sum will be sum=A[i]+A[j+1], j+1<N
b) when j!=i+1, the next sum will be min( sum01=A[i]+A[j+1] and sume02=A[j-1]+A[j]), j+1<N

3) 3 elements,
we need to compare
a) when j==i+1 && k==j+1, the next sum will be sum=A[i]+A[j]+A[k+1], k+1<N
b) when j==i+1 && k>j+1, the next sum will be min(sum01, sum02), k+1<N
sum01=A[i]+A[j]+A[k+1],
sum02=A[i]+A[j+1]+A[k],
c) when j>i+1 , the next sum will be min(sum01, sum02),
sum01=A[i]+A[j+1]+A[k],
sum02=A[i+1]+A[j]+A[k],

- SeekingJob April 13, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Great solution!

- LOL April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Good one. there will be one small tweek. When all are non adjacent for 3 cases it will be min of all three
c) when j>i+1 , the next sum will be min(sum01, sum02,sum03),
sum01=A[i]+A[j+1]+A[k],
sum02=A[i+1]+A[j]+A[k],
sum03=A[i]+A[j]+A[k+1],

- WellSaid August 14, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Try to simplify this questin, we only consider a+b, but not a+b+c.
int node1; // initialize with 0 which represents index of A[0]
vector<Sum2Node> nodes2; // first initialize with A[0]+A[1], it represnets sum from A[i] + A[j], let's use {i, j}
each time, we compare all nodes.

if the min is from node1, then put A[node1] into heap and node1++;
if min is from nodes2[k], in such case, if k == nodes2.size()-1, then we need to compare {i,j} and {i+1, i+2}
if {i+1, i+2} is smaller, we add a new node to nodes2.
both cases we move {i,j} to next {i,j+1}, and if j>=A.size(), remove this node.
e.g. A={1,2,3,4,5,6}
the stack would like:
1
{1,2}
....
6
{1,5}
{2,3}
...
node1=none
{2,4}
...
{2,6}
{3,4}
...
{3,5}
...
{4,5}

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

<pre lang="" line="1" title="CodeMonkey90608" class="run-this">public class KBiggestElement {

private static int[] comPossiblities = new int[]{3, 5, 7};

public static void main(String[] args) {
int[] values = new int[]{1, 3, 5, 8, 16, 30, 35};
int cursor = 0;
int combinationCursor = 0;
int currentCombination = 0;

List<Integer> res = new ArrayList<Integer>(values.length);
for (int i = 0; i < values.length; i++) {
int combiValue = getCombiValue(values, combinationCursor, comPossiblities[currentCombination]);
if (combiValue < values[cursor]) {
res.add(combiValue);
currentCombination++;
if (currentCombination >= comPossiblities.length) {
currentCombination = 0;
combinationCursor++;
}
} else {
res.add(values[cursor++]);
}
}

System.out.println("res: " + res);


}

private static int getCombiValue(int[] values, int combinationCursor, int comPossiblity) {
int res = 0;
if (comPossiblity == 3) {
if (combinationCursor + 1 >= values.length) {
return Integer.MAX_VALUE;
}
res = values[combinationCursor] + values[combinationCursor + 1];
} else if (comPossiblity == 5) {
if (combinationCursor + 1 >= values.length) {
return Integer.MAX_VALUE;
}
res = values[combinationCursor] + values[combinationCursor + 2];
} else {
res = values[combinationCursor] + values[combinationCursor + 1] + values[combinationCursor+2];
}

return res;
}
}
</pre><pre title="CodeMonkey90608" input="yes">it's O(n) solution. No need for heap.

for every next smallest value, there are two possibilities, a single value or a combined value. For the combined the value, it has three possibilities 110, 101, 111.
So keep two cursors, one for the single value, one for the combined start value and move forwards.

Negatives need no special treatment.
</pre>

- Anonymous April 14, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

it is not correct,

- Anonymous April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

It's pretty WRONG solution! Run the code atleast for 10-20 inputs trying to catch different elements combination.

- LOL April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Maintain 3 vectors, the first one contains the element themselves, second one contains the sums of two, and the third one contains the sums of three, here's how to update these 3 vectors:

1. We get the numbers from the original array one by one.
2. It will first be appended to the first list
3. For each element in the first list, add the current number and append to second list
4. For each element in the second list, add the current number and append to third list

Now we have 3 sorted vector, we can just perform some lazy evaluation (extract the min of the first elements of each one) once we have extracted k numbers from the original array (when we can guarantee that the top k numbers we need are all in the 3 vectors).

- airfang613 April 15, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Do you dare to take challenge to code it. Giving only idea is far away from REAL solution. Needless to talk about coding it 100% correctly.

- anon April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

In fact, I don't really like the idea of simply posting code here (especially without proper indentation). You might just make others spending half an hour figuring out that you got it wrong!

I think getting the idea correct is more important than its implementation.

With that said, I will post code later on. Stay tuned.

- airfang613 April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Please see next comment for the code.

I don't think this is the elegant solution as a lot of space and time is wasted in computing and storing the pairwise and triplet sums, there should be a smarter (or lazier) way to generate the result vector. Nonetheless, it is a working solution.

- airfang613 April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

As I suggested, idea seems plausibly correct very often. When the code is there (along with brief idea), it's easier for others to see through your code, and catch bug. Apparently, your idea is wrong, as someone below posted link to your program which gives many errors.

I'm still up with buried.shopno's O(k logk) solution which I think optimal and seems correct as he did rigorous verification with random cases.

- anon April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I am sorry, but perhaps either you or me understand the problem wrong.

According to my understanding the number of values in the original array EQUALS to the number of values that need to be extracted.

So my first loop only expects exact same numbers from the original array.

- airfang613 April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

int main() {
  int A[7] = {3,4,5,15,19,20,25};
  vector<int> original(A,A+7);
  vector<int> first;
  vector<int> second;
  vector<int> third;
  
  // now assume k = 7
  int k = 7;
  
  for (int i = 0; i < k; ++i) {
    for (int j = 0; j < second.size(); ++j)
      third.push_back(original[i]+second[j]);
    for (int j = 0; j < first.size(); ++j)
      second.push_back(original[i]+first[j]);
    first.push_back(original[i]);
  }

  vector<int> result;
  while (k > 0) {
    while (!first.empty() && first[0] <= second[0] && first[0] <= third[0] && k > 0) {
      result.push_back(first[0]);
      first.erase(first.begin());
      k--;
    }
    while (!second.empty() && second[0] < first[0] && second[0] <= third[0] && k > 0) {
      result.push_back(second[0]);
      second.erase(second.begin());
      k--;
    }    
    while (!third.empty() && third[0] < first[0] && third[0] < second[0] && k > 0) {
      result.push_back(third[0]);
      third.erase(third.begin());
      k--;
    }
  }

  k = result.size();
  for (int i = 0; i < k; ++i)
    cout << result[i] << " ";
  cout << endl;
  
  return 0;
}

- airfang613 April 15, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Your code doesn't give right output I guess. Check out your program output here for k = 50 with 8 input : ideone.com/0S8Y1

You basically enumerates all possible 1,2 and 3-way combination among first k numbers. This is quite inefficient as it's O (k^3).

The main part of your loop is also taking O(k^2) as you call erase to alter the vector. It's pretty simple to make it O(k) though.

Waiting to see your corrected code.

- LOL April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Here you can see correct output (some other's solution) for different input cases: ideone.com/M5gjR

- LOL April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks for your verification, I have described above the problem that causes my program to behave improperly. In short, according to my understanding of the problem, the number of elements in the array and the number of elements to be extracted are the same (it was the same notation k).

So I still believe my solution is correct. Also I have already mentioned above that this is indeed not an efficient solution. It is merely A solution.

- airfang613 April 15, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The above algorithm is wrong altogether as others pointed already.

Input:
A[20] = {1,3,6,8,12,15,16,20, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200 }

k = 20

Output: 1 3 4 6 7 8 9 9 10 11 12 12 14 13 15 15 15 16 17 16

output must be sorted. 13 comes after 14, 16 comes after 17.

- anonymous April 16, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I'm surprised to see how you claim your wrong code as correct. Your assumption is okay that k = size of array. See your program incorrect output for k = size of array = 20 here : ideone.com/WY3z6

One suggestion for you, before claiming your solution is correct or wrong, analyze it systematically. Thanks.

- LOL April 16, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I stand corrected.

Thank you very much for the suggestion.

- airfang613 April 16, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Note that your B array will be constructed from atmost p elements from A, p << k. You can bound p as follows: Say you choose the first p elements; they are guaranteed to be ordered. The total number of combinations of these p taking one, two or three at a time is pC1 + pC2 + pC3; this has to be bounded by k. So, go through p from 1 to k, and detect which p results in the sum being just greater than k; that's the p elements in B you are interested in. Now keep generating one at a time, two at a time and three at a time combinations from these p elements and put them into a min-heap; once you pull out k elements from the min-heap you are done. Time complexity? O(k) [for the initial test] + O(k'log k') [ where k' = pC1 + pC2 + pC3]; ideally k' would not be wildly different from k.

- A quick bound April 22, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

struct SumNode3{
	int i;
	int j;
	int k;
	int sum;
	int key;
	SumNode3(int* A, int i, int j, int k):i(i), j(j), k(k), sum(A[i] + A[j] + A[k]){
		key = A[i] + 100*A[j] + 10000*A[k];
	}
	SumNode3(int* A, int i, int j):i(i), j(j), k(-1), sum(A[i] + A[j]){
		key = A[i] + 100*A[j];
	}
	SumNode3(int* A, int i):i(i), j(-1), k(-1), sum(A[i]){
		key = A[i];
	}
};

vector<int> sortWithSum3(int*A, int n, int ksmall){
vector<SumNode3> sums;
sums.push_back(SumNode3(A, 0));
sums.push_back(SumNode3(A, 0, 1));
sums.push_back(SumNode3(A, 0, 1, 2));
unordered_set<int> set;
set.insert(sums[0].key);
set.insert(sums[1].key);
set.insert(sums[2].key);

vector<int> ret;
while(ksmall-- > 0 && !sums.empty())
{
int k = 0;

for(int j=1; j<sums.size(); j++)
{
if (sums[j].sum < sums[k].sum)
{
k = j;
}
}
ret.push_back(sums[k].sum);
cout<<sums[k].sum <<" i="<<sums[k].i<<" j="<<sums[k].j<<" k="<<sums[k].k<<endl;
if (sums[k].j == -1) // {1,2....}
{
if (sums[k].i < n-1)
{
sums[k] = SumNode3(A, sums[k].i+1);
set.insert(sums[k].key);
}
else
{
sums.erase(sums.begin()+k);
}
}
else if (sums[k].k == -1) // { sum(1,2) ....}
{
if (sums[k].i < n-2)
{
SumNode3 next(A, sums[k].i+1, sums[k].i+2);
if (set.find(next.key) == set.end())
{
sums.push_back(next);
set.insert(next.key);
}
}
if (sums[k].j < n-1)
{
sums[k] = SumNode3(A, sums[k].i, sums[k].j+1);
set.insert(sums[k].key);
}
else
{
sums.erase(sums.begin()+k);
}
}
else// { sum(1,2,3) ....}
{
if (sums[k].i < n-3)
{
SumNode3 next(A, sums[k].i+1, sums[k].i+2, sums[k].i+3);
if (set.find(next.key) == set.end())
{
sums.push_back(next);
set.insert(next.key);
}
}
if (sums[k].j < n-2)
{
SumNode3 next(A, sums[k].i, sums[k].j+1, sums[k].j+2);
if (set.find(next.key) == set.end())
{
sums.push_back(next);
set.insert(next.key);
}
}
if (sums[k].k < n-1)
{
sums[k] = SumNode3(A, sums[k].i, sums[k].j, sums[k].k+1);
set.insert(sums[k].key);
}
else
{
sums.erase(sums.begin()+k);
}
}
}
return ret;
}

- BIN December 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Plz elaborate on the question.

- Anonymous April 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Assuming all numbers are positive:

ind = k;
  for(int i=n-1; i >= 2 && ind ;i--){
     for(int j=i-1; j>=1 && ind;j--){
        for(int t=j-1; t>=0 && ind ;t--){
           B[--ind] = A[i]+A[j]+A[t];
        }
     }
  }
  if(ind){
    for(int i=n-1; i >= 1 && ind ;i--){
       for(int j=i-1; j>=0 && ind;j--){
           B[--ind] = A[i]+A[j];
       }
  }
  if(ind){
    for(int i=n-1; i >= 1 && ind ;i--){
           B[--ind] = A[i];
    }
  }

- anon1234567890 April 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

sorry, it is wrong. Some pairs might be larger than some of the triples...

- anon1234567890 April 08, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

this is same as finding all subsets of a given set and then summming up each of those subsets

- mg April 09, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Absolutely...
Generate the subsets and check whether their sums are small enough to fit into the first k items. However some optimization must be done...instead of generating 2^n subsets...

- Vinci April 21, 2011 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Please try to explain the problem better. Not able to understand the problem

- Mayank April 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Please try to explain the problem better. Not able to understand the problem

- Mayank April 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

@mayank,

dude, the problem is very clear. please look at the example given.

- Anonymous April 09, 2011 | 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