给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
解法
凡是涉及到数组元素排列组合问题的,均可使用46.全排列中的模板:
- 使用栈储存解,使用列表储存解集
- 根据题目要求,确定是否需要去重,可以用
stack.Contains(nums[i])
或 for 循环中的指针来实现 - 压入元素,递归进行下一次压入
- 当栈中元素个数满足题目要求时,说明一个组合已求解完成,将结果添加至列表中
- 回溯,将栈顶元素取出,进行下一分支的求解
- 重复上述步骤直至循环结束
回到本题,根据题意,我们需要去重并且解的元素个数不唯一,所以我们做如下改动:
- 去重,用指针 first 指向循环开始的位置,压入元素
nums[i]
后,下一次递归的循环开始位置为i+1
- 我们定义一个参数 count 用于控制解中元素个数,将回溯法放在
for (int i = 1; i <= nums.Length; i++)
中,令参数 count = i ,遍历完成便求得了所有个数的解集 - 在解集中添加一个空列表
public IList<IList<int>> Subsets(int[] nums)
{
IList<IList<int>> res = new List<IList<int>>();
Stack<int> stack = new Stack<int>();
for (int i = 1; i <= nums.Length; i++)
{
BackTrak2(res, stack, 0, nums, i);
}
res.Add(new List<int>());
return res;
}
public void BackTrak2(IList<IList<int>> res, Stack<int> stack, int first, int[] nums, int count)//回溯法
{
if (stack.Count == count) res.Add(stack.ToArray());
else
{
for (int i = first; i < nums.Length; i++)
{
stack.Push(nums[i]);
BackTrak2(res, stack, i + 1, nums, count);
stack.Pop();
}
}
}