LeetCode | Subsets(子集)


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--;   //要减一
}








点赞