Microsoft Interview Question
SDE1sCountry: India
Interview Type: Written Test
My Idea is that:
1> If the k is the relative prime of len, you just keep move the element to its next place one by one, after len times, all elements are in place.
2> If the k is not relative prime of len, find the gcd of k and len, divide the array into gcd number of sub virtual arrays, in which sub array i is in the form of array[i+k*p], where i is in [0, gcd-1], representing the sub array, while p is in [0, len/gcd-1], the index inside the subarray. For each sub array[i], the rotate happens only in 1 increase its index p, so you can use the same logic in 1> to rotate each sub array.
Here is my uCode:
void inplaceRotate(char*str, int len, int k)
{
int cur, next;
int count;
char temp, temp2, gcd, loopLen;
if(NULL==str||k>len||k<1)
return;
//First we need to find out the gcd(len, k)
for(temp=len, temp2=k;temp!=temp2;)
{
if(temp>temp2)
temp-=temp2;
else
temp2-=temp;
}
gcd=temp;
loopLen=len/gcd;
//printf("gcd is %d\n", gcd);
for(gcd--;gcd>=0;gcd--)
{
for(cur=gcd, temp=str[cur], count=0; count<loopLen;count++)
{
next=(cur+k)%len;
str[next]^=temp;
temp^=str[next];
str[next]^=temp;
cur=next;
}
}
}
Test code:
int main()
{
int count;
for(count=1;count<10;count++)
{
char str[]="1234567890";
printf("orig %s ==> ", str);
inplaceRotate(str, strlen(str), count);
printf(" %s in %d right shift\n", str, count);
}
}
class Program
{
static void Main(string[] args)
{
int[] arr, newarr;
int k = 4;
arr = new int[7] { 10, 12, 25, 12, 56, 17, 20 };
newarr = new int [7] {0,0,0,0,0,0,0};
int p = k % arr.Length;
for (int i = 0; i < arr.Length; i++)
{
newarr[i] = arr[p];
p++;
if (p == arr.Length-1)
p = 0;
}
Console.WriteLine(arr);
Console.WriteLine(newarr);
}
}
Test result:
orig 1234567890 ==> 0123456789 in 1 right shift
orig 1234567890 ==> 9012345678 in 2 right shift
orig 1234567890 ==> 8901234567 in 3 right shift
orig 1234567890 ==> 7890123456 in 4 right shift
orig 1234567890 ==> 6789012345 in 5 right shift
orig 1234567890 ==> 5678901234 in 6 right shift
orig 1234567890 ==> 4567890123 in 7 right shift
orig 1234567890 ==> 3456789012 in 8 right shift
orig 1234567890 ==> 2345678901 in 9 right shift
#include<stdio.h>
int reverse_elements(int a[20],int first,int last)
{
int temp;
while(first<last)
{
temp=a[first];
a[first]=a[last];
a[last]=temp;
first++;last--;
}
return 0;
}
int main()
{
int a[20],len,i,k;
printf("enter the length of the array:\n");
scanf("%d",&len);
printf("enter the kth element:\n");
scanf("%d",&k);
printf("enter the array elements:\n");
for(i=0;i<len;i++)
scanf("%d",&a[i]);
reverse_elements(a,0,len-1);
reverse_elements(a,0,k-1);
reverse_elements(a,k,len-1);
printf("result array:\n");
for(i=0;i<len;i++)
printf("%d\t",a[i]);
return 0;
}
#include<iostream>
#include<stdlib.h>
using namespace std;
void swp(int * begin, int * end) {
int temp;
while(begin < end) {
temp = *begin;
*begin++ = *end;
*end-- = temp;
}
}
void rotate(int * array,int k, int length) {
cout<<length<<endl;
swp((int *)array, (int *) (array+length-1));
swp((int *)(array+(length-k)), (int *)(array+length-1));
}
int main() {
int array[5] = {12,455,76,23,45};
int k = 3;
rotate((int *)array, k, (int) sizeof(array)/sizeof(int));
for(int i=0;i<(int) sizeof(array)/sizeof(int);i++) {
cout<<array[i]<<" ";
}
cout<<endl;
return 0;
}
class Program
{
static void Main(string[] args)
{
int[] arr, newarr;
int k = 4;
arr = new int[7] { 10, 12, 25, 12, 56, 17, 20 };
newarr = new int [7] {0,0,0,0,0,0,0};
int p = k % arr.Length;
for (int i = 0; i < arr.Length; i++)
{
newarr[i] = arr[p];
p++;
if (p == arr.Length-1)
p = 0;
}
Console.WriteLine(arr);
Console.WriteLine(newarr);
}
}
this swaps the data alone not the node....
#include<stdio.h>
#include<iostream>
using namespace std;
struct list
{
int data;
struct list *next;
}*head=NULL;
struct list *insert(struct list *head,int n)
{
struct list *temp,*t;
if(!head)
{
head=new list;
head->data=n;
head->next=NULL;
}
else
{
temp=head;
while(temp->next)temp=temp->next;
t=new list;
t->data=n;
t->next=NULL;
temp->next=t;
}
return head;
}
int replace(struct list *head,int n)
{
int temp=0;
struct list *ptr=head,*ptr1=head,*t,*tt;
while(ptr1->next)
{
if(++temp>=n)
ptr=ptr->next;
ptr1=ptr1->next;
}temp=n;ptr1=head;
while(--temp)
ptr1=ptr1->next;
temp=ptr1->data;
ptr1->data=ptr->data;
ptr->data=temp;
return 0;
}
int display(struct list *head)
{
struct list *temp=head;
while(temp)
{
printf("%d\t",temp->data);
temp=temp->next;
}
return 0;
}
int main()
{
int i,n,d;
printf("enter the number of elements in the linked list:\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&d);
head=insert(head,d);
}
printf("enter the kth element to be replaced:\n");
scanf("%d",&d);
replace(head,d);
printf("thus the resultant linked list is:\n");
display(head);
return 0;
}
#include<iostream>
int main() {
int arr[] = {1,2,3,4,5,6};
int n = 6;
int *result = new int[6];
int resultIndex = 0;
for(int i = 0; i < 6; i++) {
resultIndex = (i+5) % 6;
result[resultIndex] = arr[i];
}
for(int i = 0; i < 6; i++) {
std::cout << result[i] << " ";
}
std::cout << std::endl;
}
1. reverse the array will become 654321
- dude March 25, 20132. reverse first k numbers in this array will become 564321
3. reverse n-k numbers in above array becomes 561234
run time O(n) space complexity O(1)