📅  最后修改于: 2023-12-03 15:12:42.843000             🧑  作者: Mango
给定一个由 n 个唯一整数组成的数组 nums,返回所有可能的子集(幂集)。解集不能包含重复的子集。
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
本题可以使用回溯算法来解决。
首先,将nums数组按升序进行排序,这是为了使得枚举子集时子集内元素的顺序是升序的。
接着,从长度为0的子集开始,对于每一次增加元素,都对nums数组进行一次遍历,将其添加到当前子集中,并继续进行长度增加。每次添加元素后,需要回溯到上一次的状态,将上次添加的元素删除,继续进行遍历。当子集长度达到数组长度时,说明已经构建出一个子集。
最后,将所有子集加入到解集中,即可完成求解。
以下是代码实现:
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
nums.sort()
res = []
n = len(nums)
def backtrack(start, subset):
# 当元素个数为 n 时,结束递归
if len(subset) == n:
res.append(subset[:])
return
for i in range(start, n):
# 添加元素到当前子集中
subset.append(nums[i])
# 递归,继续构建子集
backtrack(i + 1, subset)
# 删除上一次添加的元素
subset.pop()
# 从空集开始,构建所有子集
backtrack(0, [])
return res
时间复杂度为 O(2^n),即为解集中元素个数的上限。空间复杂度为 O(n),即递归栈深度的上限。
本题展示了回溯算法在求解子集问题中的应用。回溯算法的一般步骤为:定义状态,枚举所有可能的状态,检查是否符合要求,并进行回溯。掌握回溯算法的关键在于理解回溯的本质,即通过维护状态,在状态树上遍历所有可能状态,从而求解问题。