Reputation: 41
Hi Guys I been stuck on a problem for quite a while now - Here it is -
question --- given an array of size n ,find and return all subsets of this array .... do this recursively
My approach - consider an array of size 3 - {10,11,12}. Consider 1st element - I have 2 options to either take it not. So I do work for 1st element and let recusion do the rest.
int helper(int in[],int si,int n,int output[][20]){
//si - starting index , n - size
if(si == n){
output[0][0] = 0; //using 0 for null
return 1; //helper returns the number of subsets of array
}
int smallSize = helper(in,si+1,n,output);
for(int i =0;i<smallSize;i++){
output[i+smallSize][0] = in[si];
for(int k = 0;k<4;k++){
output[i+smallSize][k+1] = output[i][k];
}
}
return smallSize*2;
}
int subset(int input[], int n, int output[][20]) {
return helper(input,0,n,output);
}
I want to store all the subsets in 2-d array output and return the number of subsets.
I seem to get zeros?
Upvotes: 3
Views: 11569
Reputation: 1
This is my approach:-
int subset(int input[], int n, int output[][20]) {
if(n<=0){
output[0][0]=0;
return 1;
}
int smallOutputSize = subset(input+1, n-1, output);
for(int i=0; i<smallOutputSize; i++){
output[i+smallOutputSize][0]=output[i][0]+1;
for(int j=(output[i][0]+1); j>1;j--){
output[i+smallOutputSize][j]=output[i][j-1];
}
output[i+smallOutputSize][1]=input[0];
}
return 2*smallOutputSize;
}
Upvotes: 0
Reputation: 1
int subset(int input[], int n, int output[][20]) {
if (n==0)
{
output[0][0]=0;
return 1;
}
int count=subset(input+1,n-1,output);
int i,j;
for(i=0;i<count;i++){
output[count+i][0]=output[i][0]+1;
output[count+i][1]=input[0];
}
for(i=0;i<count;i++){
for(j=1;j<output[count+i][0];j++){
output[count+i][j+1]=output[i][j];
}
}
return 2*count;
}
Upvotes: 0
Reputation: 143
There is no need to use Si variable. Given below is the correct code. I'm assuming null value as 0 and storing the size of each row (i.e subset) at column 0, so the result starts from column 1 for every row.
int subset(int input[], int n, int output[][20]) {
// Write your code here
if(n<=0) {
output[0][0]=0;
return 1;
}
int smallOutput = subset(input+1,n-1,output);
for(int i=0;i<smallOutput;i++) {
int col = output[i][0] +1;
output[i+smallOutput][0] = col;
output[i+smallOutput][1] = input[0];
for(int j=2; j<col+1;j++) {
output[i+smallOutput][j] = output[i][j-1];
}
}
return 2*smallOutput;
}
Upvotes: 2
Reputation: 372
Your base case is incorret. It has to represent an empty array. Not sure if you can do this using native array data structure.
In general, there are multiple ways to solve the "all subsets" (or "all combinations" problem). Google for "all combinations of a set" (and the related "all permutations of a list") for other ways.
These types of problems have exponential complexity (for permutations it is factorial complexity), so be careful with your input size of N.
You have the correct idea, but are missing stuff since you are using native arrays. Since you've tagged C++, it will make life much easier if you use STL.
Here is one way to do it recursively:
vector<vector<int> > AllCombinations(vector<int> input) {
//base case
if(0 == input.size()) {
//1 element of empty/null set
return vector<vector<int> >(1, vector<int>());
}
//recursion case
const int last = input.back();
input.pop_back();
vector<vector<int> > result = AllCombinations(input);
result.reserve(result.size() * 2);
//add last element to previous result
const size_t resultSize = result.size();
for(size_t i = 0; i < resultSize; ++i) {
vector<int> tmp = result[i];
tmp.push_back(last);
result.push_back(tmp);
}
return result;
}
Complexity: O(2^N)
Upvotes: 3