Microsoft Interview Question
Software Engineer in TestsAll subsets can be easily generated by generating all the binary numbers.
initially bitArray contains all zeros.
void PrintAllSubset(int bitArray[], char set[], int length, int pos)
{
if(pos == length)
{
for(int i = 0 ; i < length ; i++)
if(bitArray[i]!=0)
cout<<set[i]<<" ";
cout<<endl;
return;
}
for(int i = 0 ; i<= 1 ; i++)
{
bitArray[pos] = i;
PrintAllSubset(bitArray, set, length, pos+1);
}
}
@insigniya
what will be initial value of "pos" when "PrintAllSubset" is called for the 1st time.
This will be a JAVA alternative of Tulley. It is O(2^n) with less space complexity than simply call recursion.
/**
* Make super set w/o calling recursion
* @param array
*/
public static void superset(int array[]){
int size = 1<<array.length;
for(int i=0;i<size;i++){
iprint(i,array);
}
}
/**
* Print out subset with the position matching the passing parameter
* @param bitInt a passing parameter e.g., 6 --> 0110
* @param array
*/
private static void iprint(int bitInt, int array[]){
int pos = array.length-1;
System.out.print('{');
while(bitInt > 0){
if((bitInt & 1) == 1)
System.out.print(array[pos]+",");
bitInt >>= 1; pos--;
}System.out.print('}');
}
The complexity of above code is O(2^N*(logN)) since for each number you are iterating over all the bits of the number.
As an alternate approach you can divide the input array into two parts and generate the subsets for each part separately and store them in an array. The time for generating subsets of each half will be O(2^(N/2)log(N/2)). After that you can do a Cartesian product of both the arrays to get all the subsets.
PS:In this case you need to consider the empty set also(See example below).
Time Complexity: O(2^(N/2)log(N/2)) + O(2^(N/2)log(N/2)) + O(2^N) = O(2^N)
Space Complexity : O(2^(N/2))
eg: A = {1,2,3,4}
Let the two generated sets(or arrays) be A1, A2.
A1 = {}, {1}, {2}, {1,2}
A2 = {}, {3}, {4}, {3,4}
A1 X A2 = {}, {1}, {2}, {1,2}, {3}, {4}, {3,4}, {1,3}, {1,4}, {1,3,4}, {2,3}, {2,4}, {2,3,4}, {1,2,3}, {1,2,4}, {1,2,3,4}.
Ignore the empty set generated.
#include<stdio.h>
#include<conio.h>
#include<math.h>
int main()
{
int a[3]={1,2,3};
int b[3]={0,0,0};
int i,j,k;
for(i=1;i<2^3;i++)// 3 here is length of array//
{
j=i;
k=2;
printf("\n{");
while(j>0)
{
b[k]=j%2;
j=j/2;
if(b[k]==1)
{
printf("%d ",a[k]);
}
--k;
}
printf("}");
}
getchar();
getchar();
return 0;
}
Try this one its output is better than the earlier one.
#include<stdio.h>
#include<conio.h>
#include<math.h>
int main()
{
int a[3]={1,2,3};
int b[3]={0,0,0};
int i,j,k;
for(i=1;i<2^3;i++)// 3 here is length of array//
{
j=i;
k=2;
printf("\n{");
while(j>0)
{
b[k]=j%2;
j=j/2;
--k;
}
for(k=0;k<=2;k++)
{
if(b[k]==1)
printf("%d ",a[k]);}
printf("}");
}
getchar();
getchar();
return 0;
}
what if, while iterating bit pattern, we also generate the opposite one.
Example:
input: [1,2,3]
Bit Operation
000 => {}, {1,2,3}
001 => {1},{2,3}
010 => {2} , {1,3}
011 => {1,2},{3}
So, at this time, although we can stop at 2^(N-1), but for each number, we need to read the whole bit pattern of the number.
Would the time complexity is O(2^(N-1)*N) => O(2^N*N)
Just curious...
/**
*
* @author Sun
*/
public class bitmap {
public static void main(String[] args){
int[] test={1,2,3,4,5};
permu(test);
}
public static void permu(int[] array){
if(array==null || array.length==0)return;
for(int i=0;i<=Math.pow(2,array.length);i++){
System.out.println();
for(int j=0;j<array.length;j++){
if((i & (1<<j))>0){
System.out.print(" "+array[j]);
}
}
}
}
}
complexity 2^n*(logn +1). 2^n we cant avoid but can we avoid additional logn factor???
- Tulley February 26, 2011