Synopsys R&D Interview Question for Senior Software Development Engineers


Country: India




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

0. Let's say your original array is A = {1, 2, 3, 4, 5, 6, 7, 8} and you wanna rotate by k = 2
1. Reverse the whole array => A' = {8, 7, 6, 5, 4, 3, 2, 1}
2. Reverse the first k elements of A' => A' = {7, 8, 6, 5, 4, 3, 2, 1}
3. Reverse the remaining elements of A' starting from the kth element => A' = {7, 8, 1, 2, 3, 4, 5, 6}
4. return A'

The reverse operation is O(1) space, so this program is O(n) time and O(1) space

Here is the code in C++

template <typename T>
void rotate_array(vector<T>& A, int k) {
	k %= A.size();

	std::reverse(A.begin(), A.end());
	std::reverse(A.begin(), A.begin() + k);
	std::reverse(A.begin() + k, A.end()); 
}

This algorithm is from Programming Pearls!

- oOZz June 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 votes

You still have to traverse the array 3 times! You can easily do this with one traversal.

- yokuyuki June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

There are NO traversals here. You just swap the elements in the array during reversal. The maximum number of swap operations are N for an array of size N and this is a linear time algorithm.

- oOZz June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I was counting each call of std::reverse as a traversal, but after understanding what std::reverse is, I can see how it is n swaps.

However, this answer would be unacceptable in an interview because they usually prohibit using convenience functions and want to see you do the actual element swaps.

- yokuyuki June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 votes

Then you can also provide the reverse routine :)

static void reverse(int *arr, int start, int end) {
     if (arr == 0) return;
        
     while (start < end) {
        int tmp = arr[start];
        arr[start++] = arr[end];
        arr[end--] = tmp;
     }
}

Look, the point here is that this is an elegant algorithm, which I've learned from Programming Pearls and I wanted to share. You can google and find even more different solutions. For instance, I can even write another C/C++ solution with memmove and memcpy to rotate any array in O(1) time with some extra storage.

- oOZz June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 votes

Why did people vote down this solution?
It's nice and elegant :)
BTW Programming Pearls is a great book.

- J. June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can u please explain how this is O(N) time

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

std::reverse(A.begin(), A.end());		// take O(n) time
std::reverse(A.begin(), A.begin() + k);	// take O(k) time
std::reverse(A.begin() + k, A.end()); 	// take O(n-k) time

Thus, the total time complexity is O(n) time.

- Pei-Jung Chen November 10, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

Rotating to the right and rotating to the left are different. However, the code is easy.

public <T> void rotateRight(T[] t, int start, int end) {
	
		if (start < end) {
			T last = t[end];
			for (int i = end; i > start; i--) {
				t[i] = t[i - 1];
			}
			t[start] = last;
		}
	}	
	
	public <T> void rotateLeft(T[] t, int start, int end) {
		
		if (start < end) {
			T first = t[start];
			for (int i = start; i < end; i++) {
				t[i] = t[i + 1];
			}
			t[end] = first;
		}
	}

- Murali Mohan June 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

No, they're exactly the same. Rotating 1 to the right is the same as rotating n-1 to the left.

- yokuyuki June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@yokuyuki

>> No, they're exactly the same. Rotating 1 to the right is the same as rotating n-1 to the left.

But rotating 1 to the right is not the same as rotating 1 to the left.

- Murali Mohan June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Dumbo

>> But rotating 1 to the right is not the same as rotating 1 to the left.

Yes, but it doesn't necessitate two functions to do it.

- yokuyuki June 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public void CircularArrayRotation(int[] arr, int sublen)
        {
            int[] brr = new int[sublen];

            int i, k=0, len = arr.Length;

            //copy the part of 1st array that needs to be rotated (ideally the size of sublen from the last element of the array) 
            for (i = len-sublen; i < len; i++)
            {
                brr[k] = arr[i];
                k++;
            }

            //Right shift the elements so that they are now stored from the last element of the array
            for (i = len - sublen - 1; i >= 0; i--)
            {
                arr[i + sublen] = arr[i];
            }

            //Now start adding the new array's elements to the original array (from the 0th index onwards) to get the final output
            for (i = 0; i < sublen; i++)
            {
                arr[i] = brr[i];
            }

            //print the resultant array
            for (i = 0; i < len; i++)
            {
                Console.Write(arr[i] + ",");
            }
        }

- Jeanclaude June 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Hi,
beside the edge cases, what do you think of this solution?
Regards,
Gio

package algorithm.arrayrotation;

public class ArrayRotation {

	public int[] rotateLeft(int[] array, int numRotation) {

		if (numRotation < 0)
			return rotateRight(array, -numRotation);
		
		if (array == null) {
			return null;
		}

		if (array.length == 0) {
			return new int[0];
		}

		if (array.length == 1) {
			return new int[] { array[0] };
		}

		int[] newArray = new int[array.length];

		int effectiveRotation = numRotation % array.length;

		for (int i = 0; i < array.length; i++) {
			newArray[i] = array[(i + effectiveRotation) % array.length];
		}

		return newArray;
	}

	public int[] rotateRight(int[] array, int numRotation) {
		if (numRotation < 0)
			return rotateLeft(array, -numRotation);

		if (array == null) {
			return null;
		}

		if (array.length == 0) {
			return new int[0];
		}

		if (array.length == 1) {
			return new int[] { array[0] };
		}

		int[] newArray = new int[array.length];

		int effectiveRotation = numRotation % array.length;

		for (int i = 0; i < array.length; i++) {
			newArray[i] = array[(array.length - effectiveRotation + i)
					% array.length];
		}

		return newArray;
	}

}

- giannigar June 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

If positive k is rotating to the right and negative k is rotating to the left, you can just adjust them all to rotate to the right by taking the modulus of k by the length of the array. Below is my Python version:

def rotate(arr, k):
	k %= len(arr)
	if k != 0:
		current = 0
		store = arr[current]
		for i in range(len(arr)):
			current = (current + k) % len(arr)
			arr[current], store = store, arr[current]
	return arr

- yokuyuki June 23, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here's an in-place right-rotate which needs only constant space and N time.

public static void rotateRight(int [] arr, int rotateBy)
{
	//If the array is <= 1, it's already 'rotated'
	if(arr.length <= 1)
		return;
	int temp = arr[0];
	//If the rotateBy is larger than array length, we need to get it into range
	while(arr.length-rotateBy < 0)
		rotateBy -= arr.length;
	//If the rotate equals the length of array or 0, we're not actually doing any
	//rotating
	if(arr.length - rotateBy == 0 || rotateBy == 0)
		return;
	//Rotate the element at 0
	arr[0] = arr[arr.length-rotateBy];
	int at = rotateBy;
	
	//While we're not back at 0, keep rotating elements
	while(at != 0)
	{
		int newTemp = arr[at];
		arr[at] = temp;
		temp = newTemp;
		at += rotateBy;
		at %= arr.length;
	}
	
	//In the case where len % rotateBy == 0, we need to take care of 
	//the 'odd' cases, since those will be skipped initially
	if(arr.length % rotateBy == 0 && rotateBy > 1)
	{
		temp = arr[1];
		arr[1] = arr[arr.length-rotateBy+1];
		at = rotateBy+1;
		
		while(at != 1)
		{
			int newTemp = arr[at];
			arr[at] = temp;
			temp = newTemp;
			at += rotateBy;
			at %= arr.length;
		}			
	}
}

- Anonymous June 24, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is a simple java function for rotating an array in clickwise by n

public static void RotateArray(int[] arr, int n)
{
int size=arr.length;
ArrayList<Integer> al=new ArrayList<Integer>(size);

for (int i=size-1; i> size-1-n; i-- )
{
al.add(arr[i]);
}

for (int j=0; j < size-n ; j++ )
{
al.add(arr[j]);
}

System.out.print("rotated array: ");
for (int k=0; k < al.size(); k++)
{
System.out.print(al.get(k));
}
}

- mechanic June 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

oOZz's code is nice and elegant.

Actually it takes 3n assignments. (Swap cost 3 assignments)
I can provide an algorithm which takes about 1n assignments. (Actually, it takes n + 2 * gcd(n,k) assignments.)
And the space remains O(1).

Let me state this question in clarified version:
Input:
1. An array A of size n
2. A rotate number k. Assume k < n.
3. Direction: For simplification, assume we always rotate to left. If we need to rotate to right, just rotate to left n-k element.
Output:
Array A after circular rotate for k elements to left.

Idea:
Since I want to use only O(1) space and n assignment. So when I move element A[j] to position 0, I have to put the correct element to the hole, and so on. This procedure make a circular movement. There is an example:
let A = {0, 1, 2, 3, 4, 5, 6, 7, 8};
let k = 6;

0 1 2 3 4 5 6 7 8   0<-6<-3<-0
6     0     3       moved elements after circular movement

The above action put all element which are multiples of gcd(n,k) to correct position.
And then, I repeat the above action, but start from A[1] to A[gcd(n,k)-1]. There is an example.

0 1 2 3 4 5 6 7 8   original
6     0     3       first cicular movement
  7     1     4     second cicular movement
    8     2     5   third cicular movement
-----------------
6 7 8 0 1 2 3 4 5   after 3 cicular movement

Here is the code in C++

void RotateArray(int A[], unsigned n, unsigned k){
	int gcd = GCD(n,k);
	for (int i=0; i<gcd ; i++ ){		//circular move from 0 to gcd-1
		int tmp=A[i], j, lastJ=i;
		for (j=i+k; j!=i ; j=(j+k)%n){
			A[lastJ] = A[j];			//1 assingment vs. Swap cost 3 assingment
			lastJ = j;
		}
		A[lastJ] = tmp;					//tmp cost another 2 assingment
	}
}

- Pei-Jung Chen November 10, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

package CrackingCodingInterview;

public class ArrayCircularShift {

	public static void main(String[] args) {
		int origArray[] = {3,2,1,4,5,6};
	    
		// right shift by k
		int k = 3;
		int size = origArray.length;
		k = k % size;
		int rightShiftedArray[] = new int[size];
     
		//right shift 
		for(int i =0 ;i < size ; i++)
		{
			int pos = i + k;
			if(pos < size)
				rightShiftedArray[pos] = origArray[i];
			else
				rightShiftedArray[pos%size] = origArray[i];
		}
		
		System.out.println("right shifted array");
		for(int ele : rightShiftedArray)
			System.out.println(ele);
		
		//left shift by k
		int[] leftShiftedArray = new int[size];
        
		for(int i=0; i < size ; i++)
        {
             int pos = i - k;
             if(pos >= 0)
            	leftShiftedArray[pos] = origArray[i];
             else
            	leftShiftedArray[pos + size] = origArray[i];
        }
		
		System.out.println("left shifted array");
		for(int ele : leftShiftedArray)
			System.out.println(ele);
	}
}

- Bhag August 29, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

package CrackingCodingInterview;

public class ArrayCircularShift {

	public static void main(String[] args) {
		int origArray[] = {3,2,1,4,5,6};
	    
		// right shift by k
		int k = 3;
		int size = origArray.length;
		k = k % size;
		int rightShiftedArray[] = new int[size];
     
		//right shift 
		for(int i =0 ;i < size ; i++)
		{
			int pos = i + k;
			if(pos < size)
				rightShiftedArray[pos] = origArray[i];
			else
				rightShiftedArray[pos%size] = origArray[i];
		}
		
		System.out.println("right shifted array");
		for(int ele : rightShiftedArray)
			System.out.println(ele);
		
		//left shift by k
		int[] leftShiftedArray = new int[size];
        
		for(int i=0; i < size ; i++)
        {
             int pos = i - k;
             if(pos >= 0)
            	leftShiftedArray[pos] = origArray[i];
             else
            	leftShiftedArray[pos + size] = origArray[i];
        }
		
		System.out.println("left shifted array");
		for(int ele : leftShiftedArray)
			System.out.println(ele);
	}
}

- bhag August 29, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

We can solve this problem using modulo operator with O(1) time and O(1) space.
if(k>n)
k%=n;//where k is number of roation and m is index
while(q--)
{

cin>>m;//index
j=m-k;
if(j<0)
cout<<a[n+j]<<endl;
else
cout<<a[j]<<endl;
}

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

if(k>n)
k%=n;//where k is number of rotation and m is index
while(q--)
{

cin>>m;
j=m-k;
if(j<0)
cout<<a[n+j]<<endl;
else
cout<<a[j]<<endl;
}

- Rohit Rumani February 06, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Hi,

My code to rotate an array anticlockwise by 'd' times.

Divide the array into 2 parts:-
A[] = [0...d-1] and B[] = [d...n-1]

Steps:-
1. reverse array A.
2.reverse arrayB
3.Reverse the whole array AB.

Code:-

package Arrays.Rotations;

import java.util.Scanner;


public class RotateArrayAnticlockwise {
public static void main(String... a) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the value of n");
int n = scan.nextInt();
int[] arr = new int[n];
System.out.println("Elements in an array:");
for (int i = 0; i < arr.length; i++) {
arr[i] = scan.nextInt();
}
System.out.println("Enter the value of d:");
int d = scan.nextInt();
rotateArrayAnticlockwiseByReverseMethod(arr, d, n);
scan.close();
printArray(arr);
}

private static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}

private static void rotateArrayAnticlockwiseByReverseMethod(int[] arr, int d, int n) {
reverse(arr, 0, d - 1);
reverse(arr, d, n - 1);
reverse(arr, 0, n - 1);
}

private static void reverse(int[] arr, int start, int end) {
int temp;
while (start < end) {
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
}

- sumit.gupta810 October 04, 2017 | 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