Google Interview Question for Software Developers


Country: India
Interview Type: In-Person




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

There is an answer at stackoverflow, (relative path /a/17249084/288875)

The solution posted there works as follows:

* treat the array as consecutive, non-overlapping blocks of size k
* calculate 'running' minima: traverse the array from left to right.
At the start of each block, reset the variable holding the minimum seen so far,
at each position i store the minimum seen so far within this
block into an array LR[i]
* do the same thing also traversing the array in the opposite direction (from right to left),
storing the running minimum values into an array RL

Given a subarray starting at position i, the corresponding minimum is obtained as follows:

* if the subarray coincides with a block (i % k == 0 for zero based indexing), the
minimum is the last running minimum value of this block in the LR array, i.e. LR[i+k-1]
* otherwise, the subarray starting at i overlaps with two blocks: the overlap on the right
ends at i+k-1, LR[i+k-1] is then the minimum value found in the fraction of the right block
up to position i+k-1.
Similarly, the minimum of the overlap region of the block on the left starting at position i
is in RL[i].
The minimum of the requested subarray is therefore min(RL[i], LR[i+k-1])

- andre.holzner September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Take a queue of size k, keep k elements in the queue at a time.
You can use min heap too.

- jay September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

This is minimum sliding array problem.

public static void MinSlideArray( int k){

		Deque<Integer> d = new ArrayDeque<Integer>(k) ;
		int[] ar = new int[]{9, 2, 3, 4, 8, 5, 6, 10};
		int i =0 ;
		for(; i<k; i++){

			while((!d.isEmpty() && ar[i] <= ar[d.getLast()])){
				d.pollLast();
			}

			d.addLast(i);
		}

		System.out.println("Min in deque");
		for(;i<ar.length; i++){

			System.out.println(ar[d.getFirst()]);

			//Removing front element out of windows
			while((!d.isEmpty() && d.getFirst() <= (i-k))){
				d.pollFirst();
			}

			while((!d.isEmpty() && ar[i] <= ar[d.getLast()])){
				d.pollLast();
			}

			d.addLast(i);
		}

		System.out.println(ar[d.getFirst()]);
	}

- Ram September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 3 vote

public static int minSum(int arr[], int k) { 
		int minsum = 0; 
		for(int i =0; i < k; i++) minsum += arr[i];
		int cSum = minsum; 
		for(int i =0; i < arr.length-k; i++) {
			cSum = cSum-arr[i]+arr[i+k];
			minsum = Math.min(minsum, cSum);
		}
		return minsum;
	}

- Mukul September 26, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

You can check the min in the first subarray B, then, if B[0] = min, recalculate the min in the new subarray, if B[0] is not min, then you only have to check if the new element is less than the actual min.
This wil be O(n*n) in the worst case, but I guess than the mean complexity is not that bad.

Other option, build a binary tree (maybe a balanced tree) with the first k elements, this will be O(k*log(k)), then the min will always be the leaf at the left (to find this will be O(log(k))).
When finding the min in the new subarray, at first we have to delete the element that's leaving the subarray (O(1) if not balanced) and add the new element (O(log(k)), then find the min (O(log(k)).
As this has to be done n-k times, the complexity will be max(n-k,k)log(k), easier, n*log(k).

- guille September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think about using a binary tree (maybe a balanced binary tree).
At first it's necessary to build the tree with the k elements, this takes O(k*log(k)).
Then to find the min just check the leaf at the left, this will be O(log(k)).
When finding the min in the next subarray, at first it's neccesary to remove the element that's leaving O(1) and add the new element O(log(k)), this has to be done n-k+1 times, so the complexity will be O(n*log(k)).
If k = 1, then it will be O(n).

- gf September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think about using a binary tree (maybe a balanced binary tree).
At first it's necessary to build the tree with the k elements, this takes O(k*log(k)).
Then to find the min just check the leaf at the left, this will be O(log(k)).
When finding the min in the next subarray, at first it's neccesary to remove the element that's leaving O(1) and add the new element O(log(k)), this has to be done n-k+1 times, so the complexity will be O(n*log(k)).
If k = 1, then it will be O(n).

- gf September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is the O(n) solution

Actually I hate this is a very difficult problem to solve in O(n).
I was doing similar exercise of implement a queue with a Max() function from the book "Elements of Programming Interviews" which has a O(n) 'Ninja' level solution which I could not get as it required a another 'ninja' solution from another problem.

This is a variation of implementing a Queue which had a Max function which used a Stack which maintained the max but in this case it maintains the minimum.

This is a very hard solution to perform this in O(n) taking O(n) space as well.

class Stack<T>()
{
	List<StackNode<T>> buffer = new List<StackNode<T>>();
	private class StackNode<T>
	{
		T Value;
		T Min;
	}

	public void Push(T val)
	{
		var node = new StackNode<T>();
		node.Value = val;
		if(buffer.Count == 0 || buffer[buffer.Count - 1].Min > val)
		{
			node.Min = val;
		}
		else
		{
			node.Min = buffer[buffer.Count - 1].Min;
		}

		buffer.Add(node);
	}

	void T Pop()
	{
		var node = buffer[buffer.Count - 1];
		buffer.RemoveAt(buffer.Count - 1);
	
		return node.Value;
	}

	public bool IsEmpty()
	{
		return buffer.Count == 0;
	}

	public T Min()
	{
		if(buffer.Count > 0)
			return buffer[Count - 1].Min;

		return default(T);
	}
}

public class Queue<T>
{
	Stack<T> A = new Stack<T>();
	Stack<T> B = new Stack<T>();

	public void Enqueue(T val)
	{
		A.Push(val);
	}

	public T Dequeue()
	{
		if(B.IsEmpty())
		{
			while(!A.Empty())
			{
				B.Push(A.Pop());
			}
		}

		return B.Pop();
	}

	public T Min()
	{
		wile(!A.Empty())
		{
			B.Push(A.Pop());
		}

		return B.Min();
	}
}

IEnumerable<int> FindMinOfSubArrays(int[] A, int k)
{
	if(A.Length < k) throw ArgumentOutOfRangeException("k");
	Queue q = new Queue();

	for(int i = 0; i < k; i++)
	{
		q.Enqueue(A[i]);
	}

	int min =	q.Min();
	for(int j = k; j < A.Length; j++)
	{
		q.Enqueue(A[j]);
		q.Dequeue();

		var temp = q.Min();
		if(min > temp)
			min = temp;

                yield return min;
	}
}

- Nelson Perez September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Its variation of Maximum slide array problem

public static void MinSlideArray( int k){

		Deque<Integer> d = new ArrayDeque<Integer>(k) ;
		int[] ar = new int[]{9, 2, 3, 4, 8, 5, 6, 10};
		int i =0 ;
		for(; i<k; i++){

			while((!d.isEmpty() && ar[i] <= ar[d.getLast()])){
				d.pollLast();
			}

			d.addLast(i);
		}

		System.out.println("Min in deque");
		for(;i<ar.length; i++){

			System.out.println(ar[d.getFirst()]);

			//Removing front element out of windows
			while((!d.isEmpty() && d.getFirst() <= (i-k))){
				d.pollFirst();
			}

			while((!d.isEmpty() && ar[i] <= ar[d.getLast()])){
				d.pollLast();
			}

			d.addLast(i);
		}

		System.out.println(ar[d.getFirst()]);
	}

- Ram September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Interesting. So, does "subarray" imply only a consecutive sequence of array elements, or can it mean any combination of k elements within the array?

- John September 19, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

consecutive by definition of array. If it wanted the minimum of any combination of k elements it would have asked for "minimum subset of size k"

- Anonymous September 21, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

consecutive by definition of array. If it wanted the minimum of any combination of k elements it would have asked for "minimum subset of size k"

- Nick September 21, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Just to make sure that the requirement for this problem is clear here:
Say, the original array is: {23, 1, 4, 17, 5, 6, 8}, n is 7, the size of the original array
If we pick a sub array of size k, where k <= n. By definition of subarray, we will have
n - k +1 number of subarray of size k within array n.
Say we pick subarray of size k=3. The following subarray are:
{23, 1, 4}
{1, 4, 17}
{4, 17, 5}
{17, 5, 6}
{5, 6, 8}

Here is the code written C:

bool FindMin(int subArray[], int startIndex, int subArraySize, int arraySize, int *minValue)
{
bool found=false;
int i;
int lastIndex;

if ( (startIndex < 0) || (subArraySize <= 0) || (subArraySize > arraySize) )
{
*minValue = 0;
return(false);
}

if (subArraySize == 1)
{
*minValue = subArray[startIndex];
return(true);
}

*minValue = subArray[startIndex];
lastIndex = startIndex + subArraySize - 1;
for (i=startIndex; i <= lastIndex; i++)
{
if (subArray[i] < *minValue)
*minValue = subArray[i];
}


return(found);
}


int main(int argc, char *argv[])
{
int testArray[]={23, 1, 4, 17, 5, 6, 8};
int k=0;
int n;
int numLoop;
int i,j;
int minValue;

printf("Enter k\n");
scanf("%d",&k);
n = sizeof(testArray)/sizeof(int);
numLoop = n - k + 1;

for (i=0; i<numLoop; i++)
{
FindMin(testArray,i,k,n,&minValue);
printf("Min value of subArray{%d .. %d} is: %d\n",testArray[i], testArray[i+k-1], minValue);
}

return(0);
}

The complexity of the above code is: k * (n-k+1) ==> k * n

- Kiet Ly September 20, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This problem can be solved in O(N) time, using a data structure call Deque, which is a queue that can be pushed/popped from both ends, in O(1) time.

The idea is: to maintain a sliding window of size K using deque. Once we push in from the right-end a number x, we need to pop out from the left-end all the numbers that are bigger than x, because these numbers cannot be a minimum of any future k-window.

I explained in details with code at this post:
capacode /array/finding-maximums-for-all-k-windows-in-linear-time/

- ninhnnsoc September 25, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is an Objective-C solution

-(NSMutableArray *)getMinValueOfSubstringsInArray:(NSMutableArray *)array withSize:(int)k{
    
    if([array count] == 0 || k <= 0){
        return nil;
    }
    
    NSMutableArray *temp = [NSMutableArray new];
    NSMutableArray *result = [NSMutableArray new];
    int min = 0;
    
    for(int i = 0; i < [array count]; i++){
        
        if([temp count] >= k){
            
            min = [[[temp sortedArrayUsingSelector:@selector(compare:)] firstObject] intValue];
            [result addObject:[NSNumber numberWithInt:min]];
        }
        
        if(i >= k){
            
            [temp removeObject:array[i-k]];
        }
        
        [temp addObject:array[i]];
    }
    
    if([temp count] >= k){
        
        min = [[[temp sortedArrayUsingSelector:@selector(compare:)] firstObject] intValue];
        [result addObject:[NSNumber numberWithInt:min]];
    }
    
    return result;
}

- oscarsanchez1937 November 10, 2016 | Flag Reply


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