Facebook Interview Question
Software Engineer / DevelopersNo, it does.
Proof: First element is chosen from the whole array uniformly at random, so the probability that itself will be chosen is 1/n. The probability that second element will be itself is the probability that the first element in the shuffled version is not the second element in the first array (and this probability is (n-1)/n) times the probability that the second element in the shuffled array will be the second element in the original array (which requires choosing itself, and that probability is 1/(n-1)). So the product makes 1/n. In general, the probability that kth element will remain in place is the probability that some (k-1) permutation of the array which does not include kth element will be chosen for the first (k-1) places in the shuffled array (which is P(n-1,k-1)/(n*...*(n-k+2))) times kth element will be chosen among the remaining elements (which is 1/(n-k+1)). This product is always 1/n.
// k is a random number between 0, i. Prob = 1/(i+1)
// Total Prob = 1/(1 * 2 * ... * N) = 1/(N!)
// this makes the shuffle to be uniformly randomly selected from the possible N! permutations of the array.
void knuth_shuffle( int * array, int size )
{
for ( int i = size - 1; i >= 0; i++ )
{
int k = (int)(rand() * i);
swap( &array[i], &array[k] );
}
}
void shuffle(Element* array, int size){
for (int i=0; i<size; i++) {
int toSwap = Rand()%size;
if(toSwap!=i) {
Element temp = array[toSwap];
array[toSwap] = array[i];
array[i] = temp;
}
}
}
Lookup the wiki on shuffling. Apparently the above is one of the most common ways of getting it _wrong_.
when we are shuffling it means permutations any permutation will work ,proof let ther be n elements hance number of permutations can be n!,now let us fix one element to its position then number of permutatons become (n-1)!.now probability beomes(n-1)!/n! which is 1/n. hence select any permutation randomly will give you the desired result.
int* shuffle_array(const int* nArray, const int nSize)
{
int* p = new int(nSize);
//float a = rand();
for (int i = 0; i < nSize; i ++) {
float a = rand();
int n = a*(i+1);
swap(p[i], p[n]);
}
return p;
}
how about :
1. loop through each number in the given array
2. for each element at index i, generate a random number between 1 and n. if the number is same as i (the probability of this happening is 1/n), the number needs to swapped out. hence save this index using a temp variable (say last_element_to_be_swapped).
3. now continue with the next element and perform step 2. if it needs to swapped out, swap it with last_element_to_be_swapped. save the current index to last_element_to_be_swapped so that we can swap for further iterations.
As long as we find two elements that needs to be swapped, we are good. The only exception is when we only find one element that needs to be swapped, then we will not be able to shuffle with any other element. I am thinking of rerunning the loop again to handle this case. there are really low chances we run into same case again.
btb, this approach take O(n) obviously.
Here is my answer, how about it?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
void shuffle(int a[], const int n);
int main()
{
int a[5]={1,2,3,4,5};
const int n = 5;
shuffle(a,n);
return 0;
}
void shuffle(int a[], const int n)
{
time_t t;
srand((unsigned) time (&t)); //srand guarantees that each rand() function will
//generate a really random number
int *b=new int[n];
int i,j;
for(i=0;i<n;i++)
b[i]=0;
for(i=0;i<n;i++)
{
j=rand()%n;
while(b[j] != 0) //if there b[j] has already saved a value
j = (j+1)%n;
b[j]=a[i];
}
for(i=0;i<n;i++)
a[i]=b[i];
delete []b;
}
- Anonymous April 18, 2009