子集
- https://leetcode.cn/problems/subsets/
描述
- 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
- 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2
输入:nums = [0]
输出:[[],[0]]
提示
- 1 <= nums.length <= 10
- -10 <= nums[i] <= 10
- nums 中的所有元素 互不相同
Typescript 版算法实现
1 )回溯1: 逐步放宽长度
function subsets(nums: number[]): number[][] {
const res: number[][] = []; // 最终结果集
// 回溯函数 path是当前子集(路径),n是层级(当前子集的长度),start是起始下标
const backtrack = (path: number[], n: number, start: number) => {
// n 分别 = 0, 1, 2, 3
if(path.length === n) {
res.push(path); // 本次长度达标后, 结束
return;
}
// 没达到n的时候,基于当前path, 继续从nums中组合元素添加元素进入下一轮验证
for(let i: number = start; i < nums.length; ++i) {
backtrack(path.concat(nums[i]), n, i+1);
}
}
// 这里是 0 ~ n 闭区间,从 0的个数 开始找子集
for(let i: number = 0; i <= nums.length; ++i) {
backtrack([], i, 0);
}
return res;
}
-
解题思路
- 要求,1.所有子集,没有重复元素
- 有出路,有死路
- 考虑回溯
-
解题步骤
- 用递归模拟出所有情况
- 保证接的数字都是后面的数字,保证子集,这样不会出现重复,无需进行判断
- 收集所有到达递归终点的情况,并返回
-
时间复杂度:O( 2 n 2^n 2n)
- 每个元素都有两种可能,存在/不存在
-
空间复杂度:O(n)
- 依然看递归的深度
- 递归堆栈
Python3 版算法实现
1 ) 方案1
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res = [] # 最终结果集
def backtrack(path: list[int], n: int, start: int):
# n 分别 = 0, 1, 2, 3
if len(path) == n:
res.append(path) # 本次长度达标后, 结束
return
# 没达到n的时候,基于当前path, 继续从nums中组合元素添加元素进入下一轮验证
for i in range(start, len(nums)):
backtrack(path + [nums[i]], n, i + 1)
# 这里是 0 ~ n 闭区间,从 0的个数 开始找子集
for i in range(len(nums) + 1):
backtrack([], i, 0)
return res
Golang 版算法实现
1 ) 方案1
func subsets(nums []int) [][]int {
var res [][]int // 最终结果集
// 回溯函数
var backtrack func(path []int, n int, start int)
backtrack = func(path []int, n int, start int) {
// n 分别 = 0, 1, 2, 3
if len(path) == n {
// 创建一个新的切片,防止后续修改影响结果
newPath := make([]int, len(path))
copy(newPath, path)
res = append(res, newPath) // 本次长度达标后, 结束
return
}
// 没达到n的时候,基于当前path, 继续从nums中组合元素添加元素进入下一轮验证
for i := start; i < len(nums); i++ {
backtrack(append(path, nums[i]), n, i+1)
}
}
// 这里是 0 ~ n 闭区间,从 0的个数 开始找子集
for i := 0; i <= len(nums); i++ {
backtrack([]int{}, i, 0)
}
return res
}