Google Interview Question for Software Engineer / Developers


Country: United States
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
8
of 14 vote

What is the problem with this?

Say the array was [1, 2, 3, 4, 5, a, b , c]

With middle pointing at 'a'. First at 1, and last at 'c', and we need to rotate so that it is

[a, b, c, 1, 2, 3, 4, 5]

You make a copy of the First, Middle Iterators, say first', middle'.

Step 1)
Now start swapping using the first' and middle' (i.e. the copies) and incrementing, till either first' becomes middle or middle' becomes last.

Step 2)
Now (tail) recursively, rotate the rest.

In the above example, after Step 1 the resulting array looks like

[a, b, c, 4, 5, 1, 2, 3]

Now you need to rotate the sub-array [4, 5, 1, 2, 3] with middle at 1.

This is O(n) with O(1) space (assuming iterators take O(1) space, and besides, you need to store them anyway...)

- Anonymous August 01, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

How do you determine the start/middle/end for the recursive call?

- Anon August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

if middle' = last, then new middle = old middle.
if first' = middle, then new middle = middle'

(or something like that, probably off by one).

The new first is easy, the the new last is very easy...

- Anonymous August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Splendid! I saw something similar in STL implementation, though it was much less clear and I couldn't understand most part. Just for the other people who come to this topic, here is the proof of linear complexity: it's easy to notice, that each time you advance the iterators, you are in fact decreasing the length of the list on next recursion call by one, thus you do no more than O(n) advancements.

- JacVlD August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Downvoted by words&lyrics. Trying to peddle your answer? Moron.

- Anonymous August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@eugene: The answer specifically mentions tail recursion.

You are right, being condescending and wrong can be embarrassing...

- Anon. August 02, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I have to disagree.

Saying it is tail recursive and claiming O(1) space is correct, succint, and makes for a clearer exposition. Trying to expand on the tail recursion would only detract from the original algorithm and make it harder to explain. Frankly, this is pretty basic stuff. If someone regards it as incorrect, it is really their problem.

As to downvoting, downvoting a competing (and correct) answer without leaving a reason is worse than calling someone a peddler or moron, IMO.

Also, imagine if the 'Moron' comment had not been made. The discussion about tail recursion would not happen and word&lyrics would probably be in the dark...

- Anon. August 02, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Well, it started with you with the preachy (and IMO condescending) comments about insults and embarrassment.

I agree though. Pointless conversation.

- Anon. August 03, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Deleting all of my replies to this thread. That was just a completely pointless conversation and no one needs to be bothered reading our stupid back-and-forth.

- eugen August 03, 2012 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

@I am not here to get votes on my answer. It's a public forum , where people contribute and get their doubts cleared. A healthy discussion is always a good thing. But This is not the way. Tail recursion is the first thing I suggested please see my post. But i didn't claimed O(1) space complexity.

- words&lyrics August 04, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@word&lyrics. For a healthy discussion, give the reason for -1, instead of silently downvoting.

Also, you solution is not tail recursive. I suggest you read up and see what it actually means, and why a tail recursive algorithm can be implemented in O(1) space.

- Anonymous August 04, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Iterative solution as C++ code

void rotate_fwd_only(int *s, int *m, int *e) {
    while (s != e) {
        int *last_m = m;
        while (s != last_m && m != e)
            swap(*s++, *m++);

        if (s != e && s != last_m && m == e) {
            swap(*s++, *e);
            m = last_m;
        }
    }
}

- tobi January 08, 2015 | Flag
Comment hidden because of low score. Click to expand.
7
of 9 vote

#include <stdio.h>

void swap (char* ch1, char *ch2) {
     char ch = *ch1 ;
     *ch1 = *ch2 ;
     *ch2 = ch ;
}

void rotate (char *str, int first, int middle, int end) {
     int next = middle ;
     while ( first != next ) {
           swap ( &str[first++], &str[next++] ) ;
           if ( next == end ) 
              next = middle ;
           else if ( first == middle ) 
                middle = next ;
     }
}
       
int main () {
    char arr[] = {'1', '2', '3', '4', '5', 'a', 'b', 'c'} ;
    int i ;
    rotate (arr, 0, 5, 8) ;
    printf ( "\n" ) ;    
    for ( i = 0; i < 8; i ++ )
        printf ( "%c ", arr[i] ) ;
    printf ( "\n" ) ;
    return 0;
}

Simple implementation as written in std::rotate

- Psycho August 02, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Push every thing in stack. And pop and swap one by one. Another is recursive approach which uses internal stack. I doubt this can be solved without using extra memory. Recursion also uses stack.

A recursive function

void rotate(int a[], int n, int *left,int right)
{
  if(right==n)
    return ;
  rotate(a,n,left,right+1);
 swap(a[*left],a[right]);
 (*left)++;
 return;

}

Call this as
int left =0,right =0;

rotate(a,n,&left,right);

- words&lyrics July 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sorry, I forgot to mention it should only use constant additional memory

- JacVlD July 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

recursion takes o(log n) internal stack memory!!

- Psycho August 02, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

LOL! -100.

- Anonymous August 07, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

if( left <= right )
swap( A, left, right );

I guess you need to add the condition, otherwise, it will swap back to original.....

- haoyu.hust August 18, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

What does a forward-only iterator mean?

Can we move forward by more than 1 step?

- Anonymous July 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Forward-only means that it has some kind of "Next" function. In C++ it would have operator++. Moving by K steps will take O(K) time.

- JacVlD July 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

If I assume that the array to be rotated is of size n and we have to rotate every element by r
Then r<n for a valid input
My approach is to start rotating from first element of the array continuously
Untill we complete one round
Then we replace the last element to be replaced with the first element of the array
Continue this cycle with second element of array and then third and so on upto r iterations
Afterwards we have a small sized problem of rotating only starting r elements with (r-n%r) steps

- ankit July 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Consider an example
Let the array be
1,2,3,4,5,6,7,8,9,10,11
r = 4
After one iteration
9,2,3,4,1,6,7,8,5,10,11
2 iteration

- ankit July 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sry for commenting in parts
9,10,3,4,1,2,7,8,5,6,11
After 3
9,10,11,4,1,2,3,8,5,6,7
After 4
9,10,11,8,1,2,3,4,5,6,7
So we can run the same algo for subarray
9,10,11,8 with r = 1

- ankit July 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This should work, the time complexity is O(n) and space complexity is O(1)


public static void rotate(int [] array, int r) {
int n = array.length;
int gcd = utility.gcd(r, n);
int term = n/gcd;

int tmp;
int cur;
int nxt;
int store;
for (int i = 0; i < gcd; i++) {
cur = i;
store = array[cur];
for (int j = 0; j < term; j++) {
nxt = (cur + r)%n;
tmp = array[nxt];
array[nxt] = store;
store = tmp;
cur = nxt;

}
}
}


public static int gcd(int a, int b) {
int bigger = a > b?a:b;
int smaller = a > b?b:a;

while (smaller > 0) {
int tmp = bigger%smaller;
bigger = smaller;
smaller = tmp;
}
return bigger;
}

- pigritia July 31, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This solution heavily relies on random access iterators, because it makes steps of size r.

- JacVlD July 31, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Do you mind sharing your O(n Log n) solution?

- Anonymous August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

My O(n log n) solution is based on reverse. You can implement reverse using simple divide-and-conquer: first reverse left part, then right part, and then simply swap them. In fact if n is a power of two, you can even implement this without any recursion, making it use O(1) space, however I don't know how to make this algorithm work in O(1) space in general case

- JacVlD August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

rotate(int *A, int k,int n)
{
reverse(A,0,n-k-1); ---->O(n) time, O(1) space
reverse(A,n-k,n-1); ---->O(n) time, O(1) space
reverse(A,0,n-1); ---->O(n) time, O(1) space
}

- Alzheimer August 01, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

It will rotate forward by k times.

- Alzheimer August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Alzheimer seems to be forgetting ForwardOnlyIterator constraint...

- Anonymous August 01, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

package org.wangbingold.datastructure.array;
/**
 * Question: 
Implement rotate function for forward-only iterators. 
Clarification: with O(1) additional memory. 
Rotate semantics should be that of std::rotate.
Example: 
Say the array was [1, 2, 3, 4, 5, a, b , c]. With middle pointing at 'a'. 
First at 1, and last at 'c', and we need to rotate so that it is [a, b, c, 1, 2, 3, 4, 5]. 
You make a copy of the First, Middle Iterators, say first', middle'.
*/

public class Rotation {
	
	private char[] array;
	
	public Rotation(char[] arrayIn){
		this.array = arrayIn;
	}
	
	/**
	 * Rotate the array in the range of [start, end] from the position of mid.
	 * */
	public void rotate(int start, int mid, int end){
		if(start>=end){
			return;
		}
		int numPart1 = mid-start;
		int numPart2 = end-mid+1;
		int p1 = start; 
		int p2 = mid; 
		if(numPart1==numPart2){
			while(p2<=end){
				char tmp = array[p1];
				array[p1] = array[p2];
				array[p2] = tmp;
				p1++;p2++;
			}
			System.out.println(this.toString());
		}
		else if(numPart1>numPart2){
			while(p2<=end){
				char tmp = array[p1];
				array[p1] = array[p2];
				array[p2] = tmp;
				p1++;p2++;
			}
			int newStart = p1;
			int newEnd = p2-1;
			int newMid = newStart+numPart1-numPart2;
			System.out.println(this.toString());
			rotate(newStart, newMid, newEnd);
		}
		else if(numPart1<numPart2){
			while(p1<mid){
				char tmp = array[p1];
				array[p1] = array[p2];
				array[p2] = tmp;
				p1++;p2++;
			}
			int newStart = p1;
			int newEnd = (p2==end)?p2:p2+1;
			int newMid = (p2>end)?p2-1:p2;
			System.out.println(this.toString());
			rotate(newStart, newMid, newEnd);
		}
	}
	
	public String toString(){
		String result="";
		for(Object obj: array){
			result+=obj.toString()+" ";
		}
		return result;
	}
	
	public static void main(String[] args){
		Rotation rotation = new Rotation(new char[]{'1','2','3','4','5','a','b','c'});
		rotation.rotate(0, 5, 7);
	}

}

- wangbingold August 02, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Is this what you're looking for?

cplusplus.com/reference/algorithm/rotate/

- paulo.koch August 02, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

package google;

public class rotate_string_with_1_additional_data_and_O_n {


public static String rotate(String aim,int index){
if(index<=0){
return aim;
}
if(index>=aim.length()){
return aim;
}
char[] test=aim.toCharArray();
do_work(test,0,index,test.length-1);
return String.valueOf(test);
}

public static void do_work(char[] test,int bIndex,int mIndex,int eIndex){

if(mIndex-bIndex==eIndex-mIndex+1){
deal_char_array(test,bIndex,eIndex,(eIndex-bIndex+1)/2);
return;
}
else if(mIndex-bIndex>eIndex-mIndex+1){
int size=eIndex-mIndex+1;
deal_char_array(test,bIndex,eIndex,size);
do_work(test,bIndex+size,mIndex,eIndex);
}
else{
int size=mIndex-bIndex;
deal_char_array(test,bIndex,eIndex,size);
do_work(test,bIndex,bIndex+size,eIndex-size);
}
}
public static void deal_char_array(char[] test,int begin,int end,int size){
if((size>(end-begin+1)/2)||(size<1)){
System.out.println("err");
return;
}
for(int i=0;i!=size;i++){
char tmp=test[begin+i];
test[begin+i]=test[end-size+1+i];
test[end-size+1+i]=tmp;
}
}

public static void main(String[] args) {
String aim="abcde123456";
String result=rotate(aim,5);
System.out.println(result);

}
}

- Chengyun Zuo August 04, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void STD_Rotate(std::vector<int>::iterator& begin, std::vector<int>::iterator& rotate, std::vector<int>::iterator& end)
{
	if(rotate == end)
		return;

	int size = rotate - begin;
	int value;

	while( rotate != end )
	{
		value = *rotate;
		while(size > 0)
		{
			*(begin+size) = *(begin+size-1);
			--size;
		}
		size = rotate - begin;
		*(begin) = value;
		++begin;
		rotate = begin+size;
	}
}

- Anonymous August 10, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Seems like you don't understand what iterators are about.

- Anonymous August 19, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Formally, for every integer n such that 0 <= n < last - first, the element *(first + n) is assigned to *(first + (n + (last - middle)) % (last - first)). Rotate returns first + (last - middle).

- Ashupriya August 13, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Simple solution :

public void rotateArrayLikeSTLRotate(int[] arr) throws Exception
	{
		if(arr != null && arr.length > 1)
		{
			int len = arr.length;
			int mid = (len-1)/2;
			int start = 0;
			int end = len - 1;

			for (int i = 0; i <= mid; i++)
			{
				//Swap i th element with end-mid+i th element
				int temp = arr[i];
				arr[i] = arr[end - mid + i];
				arr[end - mid + i] = temp;
			}

		}
		else
		{
			throw new Exception("Invalid input parameters");
		}
	}

- Ashupriya August 13, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Well... cplusplus.com has it all

cplusplus.com/reference/algorithm/rotate/

It is basically anonymous' solution converted to an iterative version

- airfang613 August 19, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

How about Jigsaw Algorithm for this. That is mentioned in Programming Pearl by John Bently.

- Andy2000 August 28, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;
typedef vector<int>::iterator viter;

void swap(int *a, int *b) {
        int tmp = *a;
        *a = *b;
        *b = tmp;
}

void myRotation(vector<int>& vec,
                viter middle) {
        viter first = vec.begin();
        viter last = vec.end();
        viter next = middle;

        while(first != next) {
                swap(*first++, *next++);
                if(next == last) next = middle;
                else if(first == middle) middle = next;
        }
}

int main() {
        int arr[] = {1,2,3,4,5,6,7};
        vector<int> vec(arr, arr+sizeof(arr)/sizeof(int));
        copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
        cout << endl;
        myRotation(vec, vec.begin()+2);
        copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
        cout << endl;

        return 0;
}

- Anonymous September 22, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Suppose you want to rotate array by K so first reverse last K elements i.e array[n-K+1...K], then reverse array[1..n-k], then reverse entire array array[1...n] and you will get the result.

Example:
array=[1,2,3,4,5,a,b,c]
K=3, here
reverse array[n-K+1... n] so the array will become [1,2,3,4,5,c,b,a].
Now reverse array[1...n-K], array will become [5,4,3,2,1,c,b,a].
Now reverse entire array and array will become [a,b,c,1,2,3,4,5].

Time complexity: O(n), Space complexity: O(n)..

- kunal.id89 November 22, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Why post a solution with linear extra memory when there are plenty answers with constant?

- JacVlD January 31, 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