78. 子集
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subsets
著作权归领扣网络所有。
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
方法一:迭代法实现子集枚举
时间复杂度:O(n x 2^n)
空间复杂度:O(n)
0/1 序列 | 子集 0/1 | 0/1 序列对应的二进制数 |
---|---|---|
000 | {} | 0 |
001 | {9} | 1 |
010 | {2} | 2 |
011 | {2, 9} | 3 |
100 | { 5 } | 4 |
101 | { 5, 9} | 5 |
110 | { 5, 2} | 6 |
111 | {5,2,9} | 7 |
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
if (! nums) {
*returnSize = 0;
return NULL;
}
int max = 1 << numsSize;
int **res = (int **)calloc(sizeof(int*), max);
*returnColumnSizes = (int *)calloc(sizeof(int), max);
for (int i = 0; i < max; i++) {
int j = 0;
int k = 0;
res[i] = (int *)calloc(sizeof(int), numsSize);
while( j < numsSize ) {
if ( i & (1 << j) ) {
res[i][k++] = nums[j];
}
j++;
}
(*returnColumnSizes)[i] = k;
}
*returnSize = max;
return res;
}
方法二:逐个枚举追加元素
逐个枚举,空集的幂集只有空集,每增加一个元素,让之前幂集中的每个集合,追加这个元素,就是新增的子集。
非递归写法:
class Solution {
/**
* @param Integer[] $nums
* @return Integer[][]
*/
function subsets($nums) {
$res = [[]];
for ($i = 0; $i < count($nums); $i++) {
foreach($res as $k => $v) {
$new = array_merge($v, [$nums[$i]]);
array_push($res, $new);
}
}
return $res;
}
}
递归写法:
class Solution {
/**
* @param Integer[] $nums
* @return Integer[][]
class Solution {
*/
function subsets($nums) {
$res = [[]];
$this->recursion($nums, 0, $res);
return $res;
}
function recursion($nums, $index, &$res) {
if ( $index < count($nums) ) {
foreach ($res as $val) {
$res[] = array_merge($val, (array)$nums[$index]);
}
$this->recursion($nums, $index+1, $res);
}
}
}
方法三:回溯法
class Solution {
/**
* @param Integer[] $nums
* @return Integer[][]
**/
private $res = [];
function subsets($nums) {
$this->dfs($nums, 0, []);
return $this->res;
}
function dfs($nums, $start, $path) {
array_push($this->res, $path);
for ($i = $start; $i < count($nums); $i++ ) {
array_push($path, $nums[$i]);
$this->dfs($nums, $i+1, $path);
array_pop($path);
}
}
}