Given a set of distinct integers, S, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
For example,
If S = [1,2,3]
, a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
题目解析:
方案一:笨蛋方法
这题和上一题有些类似。不过这里没有限制个数,输出所有的情况。每个数据都可选可不选,有2^n种情况。采用的递归方式和上题一样,不过当数据begin==n的时候,要额外进行输出。不然栈里面有数据,但是得不到显示。
代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int *buf;
int len;
}Stack;
void subsets(int arr[],int n,int begin,Stack *S)
{
if(begin > n){ //这里可以写成begin>=n,但子函数最后的输出要写进去,
return ; //换成begin>n 后,让后面的输出处理begin==n的情况
}
for(int i = begin;i < n;i++){
S->buf[S->len++] = arr[i]; //选择
subsets(arr,n,i+1,S);
S->len--; //不选择,下次循环进行递归
}
//当i==n的时候,已经退出了循环,但是数组中还有数据,就要进行输出
if(S->len == 0){
printf("$\n");
return ;
}
for(int i = 0;i < S->len;i++)
printf("%d ",S->buf[i]);
printf("\n");
return ;
}
int main()
{
int arr[] = {1,2,3,4};
int n = sizeof(arr)/sizeof(int);
Stack S;
S.buf = (int *)malloc(n * sizeof(int));
S.len = 0;
subsets(arr,n,0,&S);
free(S.buf);
return 0;
}
方案二:
真是笨啊!递归怎么都没学好,网上看了相关代码后,才知道是不用额外的循环的。这层循环选还是不选,直接递归到深层次。可能受到DFS的影响,递归要放在循环当中。要及时改正。
void subsets(int arr[],int n,int begin,Stack *S)
{
if(begin >= n){ //这里可以写成begin>=n,但子函数最后的输出要写进去,
if(S->len == 0){
printf("$\n");
return ;
}
for(int i = 0;i < S->len;i++)
printf("%d ",S->buf[i]);
printf("\n");
return ; //换成begin>n 后,让后面的输出处理begin==n的情况
}
subsets(arr,n,begin+1,S);
S->buf[S->len++] = arr[begin];
subsets(arr,n,begin+1,S);
S->len--; //要减一
}