Google Interview Question for Software Engineer / Developers


Country: United States
Interview Type: Phone Interview




Comment hidden because of low score. Click to expand.
7
of 9 vote

A variation of the matrix chain multiplication should work.
Let the number at each vertex and the (clockwise) next edge be a single element.

struct element {
      int num;
      char op;
}pol[N];

Initialize a 2D matrix m[NxN]

Let m[i,i] = pol[i] for 1 <= i <= N

Let m[i,j] be the maximum value that can be achieved from the subset of elements from index i to index j.

Using the recursive equation :
m[i,j] = max { m[i,k] [operation for element at index k] m[k+1,j] } :: for 1 <= i <= k <= j <= N

This would give the maximum value if the list was linear, but since it is a circular linked list, repeat the entire procedure for the different start points in the circular linked list.

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

this makes sense. I wrote some code to elaborate the idea. let me know if I get it right. time complexcity O(n^3)

assume input as two arrays: list[N] has N integers, operator[N] has N corresponding operators

int dp[][]=new int[N][N]; /* row i represents computing with starting point of list[i] and column j represents the max result with j numbers after list[i];*/

int max=Integer.MIN_VALUE;

for(int i=0;i<N;i++){
dp[i][0]=list[i];}

for(int j=1;j<N;j++){
for(int i=0;i<N;i++){
for(int k=0;k<j;k++){

int val=compute(dp[i][k],operator[(i+k)%N],dp[(i+k+1)%N][j-k-1]);

if(val>dp[i][j]) dp[i][j]=val;
if(val>max&&j==N-1) max=val;
}}}

return max;

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

It seems overall complexity is O(n^4)

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

why O(n^4)? count the for loops and you'll see it's O(n^3)

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

I am talking about original Kyuubi's solution

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

I think this might have a problem since the the integers are allowed to be negative:
since it is not true that max{m[i,k] [operation m[k+1,j]} is always the right thing to look at, since if m[i,k] is negative, we want m[k+1,j] to be as small as possible...

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

so to fix this, we probably need to carry the max, and the min

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

Example: given a quad, (1)--e1(+)--(2)--e2(*)--(-2)--e3(*)--(3)--e4(+)--(1). Removing edge e3 will result in a triangle: (1)--e1(+)--(2)--e2(*)--(-6)--e4(+)--(1).

- zilchistDeepblue January 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

It reminds me matrix-chain-multiplication but with start point at any vertex. Complexity of matrix-chain-multiplication is O(n^3) so the complexity of this algorithm is O(n^4). Here is algorithm:

int result(int[] vertices, Op[] edges) {
		int [][] dp = null;// initialize with -Integer.min_value and i,i with vertices [i]
		int n = vertices.length;
		int result = Integer.MIN_VALUE;
		for (int startVertex = 0; startVertex < n; startVertex++) {
			for (int length = 2; length <= n; length++) {
				for (int first = startVertex; first <= n - length + startVertex; first++) {
					int last = first + length - 1;
					int max = Integer.MIN_VALUE;
					for (int divider = first; divider < last; divider++) {
						max = Math.max(max, edges[first % n].exec(dp[first % n][divider % n], dp[(divider + 1) % n][last % n]));
					}
					dp[first][last] = max;
				}
			}
			
			result = Math.max(result, dp[startVertex][(startVertex + n) % n]);
		}
		
		return result;
	}

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

Assuming this would be kept in a circular linked list, traverse it once and collapse vertices as you see addition operation. After the first pass you will be left with only multiplication edges. In the second pass do the multiplications and the result is what you are looking for.

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

Not considering negative integer values or zero for that matter.

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

surely you should consider negative numbers.

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

wrong. understand ques properly.

- A March 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

seems like a NP problem. Can be solved using recusrsion:
Repeat for each edge: collapse edge, call recursively, restore edge.
The answer is the maximum value returned from all the recursive calls in the loop above.
Complexity: O(N!) Space: O(N)

- gen-y-s January 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

The ending condition for the recursion is what's specified in the question (when there are two edges left).

- gen-y-s January 17, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Please write your algo/ pseudocode.

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

A circular variant of matrix chain multiplication algorithm can be used. In the original solution, in the N*N array (say A), only cells with i <= j are filled, but here we would like to fill cells for which i>j as well.

Recursive definition:
V[0...N-1] - list of values on the vertices.
O[0...N-1] - list of operators.. Oi is the operator on edge connecting vertices i and i+1.

A[i, j] = Vi                  if i == j
         = max { Ok(A[i,k], A[k,j] }  for k: i->j if i<j
                                                     for k:i->N-1 and k:0->j if j<i

Example: V[-2, 3, 2, 4, -8, 5], O[*, +, *, *, +, *]

A:

iter1
-2 0 0 0  0 0
 0 3 0 0  0 0
 0 0 2 0  0 0 
 0 0 0 4  0 0 
 0 0 0 0 -8 0 
 0 0 0 0  0 5 

iter2:
-2 0 0    0    0   -10
-6 3 0    0    0      0
 0 5 2    0    0      0 
 0 0 8    4    0      0 
 0 0 0 -32  -8      0 
 0 0 0     0 -3      5

and so on to fill the whole table. And the maximum element in the filled array is the answer.
O(n*n) time+ O(n*n) space.

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

it'll be O(n^3) since you have different starting point

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

I think matrix chain multiplication algorithm can be applied in this problem. Comparing to classical dynamic program method, what we need to do here is to store two values for a random combination[i, j]: the positive number with largest abstract value; the negative number with largest abstract value.(Since we need to handle * and + operations)

- Evan April 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

is there any operator presidency means to say we can go sequential or first multiplication then addition ..

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

go sequential.

- A March 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 5 vote

dynamic programming will give you the solution in O(n*n) + O(n*n) complexity
Here is solution :
lets say you have hexagon( with following 1(15)-2(9)-3(12)-4(1)-5(7)-6(12)-1(15)), where values written in *()* is the value at each node
Now make a 2d matrix of size 6x6, write these values in the main diagonal,

15.24.36..37.44.56
.......9...21.22.29.41
............12.13.20.32
....................1..8..20
........................7..19
.............................12

the right most corner value is the answer

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

where are the operators? they are also given as input

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

ok, I have taken + as operator but because i have used dynamic programming here, so the operator does not matter, i will adjust accordingly.

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

can you elaborate with some code? I can't get it how to use dp for this. what are the states?

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

I understand what he's saying. Everyone here is trying to solve the problem by picking one starting point, but the truth is, you can have any vertice be a starting point. If you were to assume addition as the only operation for simplicty sake, you could start at each vertice 1,2,3...N and have an NxN matrix from this system of equations.

You put each successive vertice in the diagonal because:

1.) Row 1 is the value of the each vertice after performing an addition operation, starting from vertice on E1
2.) Row 2 is the value of each vertice, starting from the vertice ending at E1 and beginning at E2.
3.) If you follow this process, you have a system of equations that form a matrix. Solving for the right most column in one row, will produce the maximum value.

My thoughts on this question: I don't think they ever wanted you to write code. I think they wanted to see if you understand the problem. But ...I could be wrong.

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

So are you saying that this problem is just about where to start first and then compute them vertex by vertex sequentially? I'm afraid you can't just do it just sequentially. say 1+2+3*4+5*1, you have to both compute 1+2+3 and 4+5 first, then multiply them. and there may also be negative numbers which can't be treated by adding first.

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

@zyfo2, here is the solution of your example :
input is 1+2+3*4+5*1
so we create a matrix of size 6*6
with all these operations we get following matrix call it M[1:6,1:6]

1..3..6..24..54..54
....2..5..20..45..45
........3..12..27..27
..............4....9....9
....................5....5
..........................1

Now you man ask me how do i decide the resultant operator, the resultant operator is decided based upon from where we want to split the operation,
for example for calculation of M[1,5] we do following
M[1,5] = max(1+45,3+27,6*9,24+5) = 54

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

I get you. but you are only calculating the max for 1:5 and 2:6, it's also possible the max will be from a different starting point.
for example (-1) * 2 +3 *(-4) + (-5) +(-1) you can't get the max from 1:5 or 2:6, the max should be ((-5)+(-1)*2+(3))*(-4). I posted my solution already. you can check it.

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

Sonesh, Why a DP solution is required which has Time=O(n*n) and Space=O(n*n)? One could solve it in constant space by a brute force method.

We know: To compute the final value from a particular starting node/ vertex (say V(i) ), it is necessary to sequentially computed the result. This computation process will take O(n) time for each vertex.
Now, if we do this for 'n' different starting vertices, we have O(n*n) time. We see that no extra space is utilized in this algorithm which can help us reduce time complexity.

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

Sonesh - Your approach is not up to the expectation. It takes lot of assumptions. You have to understand that we can merge two vertices into "one vertex", in any direction, and at every step of reducing the polygon size by one vertex. There are certain basics of dynamic programming which a problem needs to qualify so that it can be solvable using this technique. I doubt this problem qualifies for dynamic programming.

Please justify your approach by writing a pseudo code and it should meet expectations of the problem submitted.

- Cecil Woods March 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

xcode - Your approach is acceptable only if we have a constraint wherein we are not allowed to change the direction while computing the total value. That is, if we started clockwise, we have to compute it clockwise and sequentially; If we started anti-clockwise, we have to compute it anti-clockwise and sequentially. This constraint is not given the problem submitted! Think of something without having this constraint.

- Cecil Woods March 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Can we not do this as a MST Problem ? Minimum spanning tree ?

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

Can we not do this as longest path?

Can we not do this as weighted cycle finding?

Can we not do this as <insert random thing>?

- Sir Chasm. January 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 3 vote

The last step is not clear what is the expectation.
But I think the you should make all the + operations first and after the * to calculate the maximum summary. (assumption the numbers>1 and all integers.)
So, Do first all the + operations. It's just 0(n).
After that we will have only * operations. Do all of them. O(n)
You will have the result. With O(2n)= O(n).

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

There would be negative values in the vertexes, so doing + firstly is not the optimal solution.

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

Solve it sequential.

- A March 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

The way I see it is as follows:

- call the vertices of the polygon P: p0, p1, ..., pn
- think of P as a vertex V0
- from this vertex V0 you have n edges, each one going to a n different vertices: V1_1, V1_2, .., V1_n
- V1_i is the polygon resulting from removing edge i from P
- the edge between V0 and V1_i is the result of the operation marked by edge i: oper(pi-1, pi)
- from each V1_i you have n-1 new edges to n-1 new vertices
- continue forming the "super graph" until you have a polygon of 2 edged with 2 vertices

What we are looking for is for the longest path with the heaviest weight.

In this super graph we have n! vertices, and the problem is NP.

- super-graph January 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

I think we can use just greedy approach. I.e. for polygon with k edges find a pair (p, q) which produces the maximum number: (p ,q) = max ({i operation j : i, j - adjacent edges)

Then just call a recursion on polygons:
1. Let function CollapseMaxPair( P(k) ) - gets polygon with k edges and returns 'collapsed' polygon with k-1 edges
2. Then our recursion:

P = P(N);
     Releat until two edges left
         P =  CollapseMaxPair( P )
     maxvalue = max ( two remained values)

What do you think?

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

Greedy isn't always optimal. Consider the following triangle:

0
 +   x
5  x  0

With the greedy approach, 5 + 0 will be collapsed first, leaving only 5 x 0 = 0. The optimal is to collapse 0 x 0, then choose 5 + 0 over 5 x 0.

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

If the numbers are a and b then:
- if a <= b <= 0 --> use *
- if a < 0 < b --> use +
- if 0 == a and 0<= b --> use +
- if 1 == a and 1<= b --> use +
- else /* 1 < a <=b */ --> use *

And then does not matter which edge you start with.

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

you misunderstood the problem. the operator is fixed, you can't choose * or +. what you can only choose is where to start and the order of the computation. for example a triangle 2+3*4+2, you can choose to make it like 3*(4+2) or (2+3)*4 or 2+3*4

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

1. choose 1 gabage value (for the last operation).
- if the number of (-) vertexs is 2k, the gabage vertex should be the smallest (+) vertex.
- if the number of (-) vertexs is 2k+1, the gabage vertex should be the biggest (-) vertex.
2. if the vertex value is either 0 or 1 use '+'
3. else use '*' operator..
(2.3 from Karthik Vvs's)

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

no. wrong. sorry for confusion.
there's a bunch of 0,-1,1,-2,2. I should think more.

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

You can do this in O(2n).
Start at any node. Push back that node's value on to a vector. When you traverse to the next node, perform the operation that takes you to that node on every number in the vector with the value of the next node. Repeat until you are back at your starting node.
The value at index 1 of your vector is the value for the starting node, it's your current best_max. Then, for each entry in the vector, move to the next node in the polygon, performing the correct operation to get you to that node on every entry in the vector. Before you move on to the next vector entry, compare against your best_max. best_max will have the answer.

- lolo January 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

traverse each node and merge edges in this order.
1. with both vertices -ve and (*) op, as this will increase the +ve vertices in polygon.
2. with one vertices +ve and one -ve and op (+). this will try to nullify the -ve of nodes.
3. with one vertices +ve and one -ve and op (*).
4.with both vertices -ve and (+) op,

as in 4 pass we will merge all the edges with maximum result.

- iictarpit February 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 vote

As the question is to find the maximum value..
1.if the vertex value is either 0 or 1 use '+'
2.else use '*' operator..
3.for example if the vertices values are in order 0,4,1,3,2,5..then the max result is ((0+4)+1)*3*2*5
code is as follows:

int result=0;
  for each vertex in polygon P:
        if(vertex.data==0 || vertex.data==1)res+=vertex.data; //considering vertex as a node 
        else res*=vertex.data;
  return res;

- Karthik Vvs January 17, 2013 | Flag Reply
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