- Subsets
Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
1 | Input: nums = [1,2,3] |
方法一:枚举
一次处理一位,循环处理每一位即可.注意,在枚举各位之前必须将数组排序,保证相等元素相邻。 比如对于题目中给的例子 [1,2,3] 来说,最开始是空集,接下来首先处理第一位1,于是就在空集上加1,为 [1],现在我们有两个子集 [] 和 [1].然后来处理2,我们在之前的子集基础上,每个都加个2,可以分别得到 [2],[1, 2],那么现在所有的子集合为 [], [1], [2], [1, 2],用同样的方法处理3可得 [3], [1, 3], [2, 3], [1, 2, 3], 再加上之前的子集就是所有的子集合.
1 | class Solution { |
方法二: 回溯
1 | class Solution { |
依次形成以索引0处开头的所有子集、以索引1处的元素开头的所有子集,直到以最后一个元素开头的子集。
方法三: 位操作
思路:为数组中所有的数分配一个状态,状态0表示这个数不在子集中出现,状态1则表示这个数在子集中出现.对于一个长度为n的数组,每个数组都有出现和不出现两种情况,所以共有2n种情况.因此,把1 - 2n-1-1转换为对应的二进制形式,再将这个二进制字符串转换成子数组即可.
1 | class Solution { |
Subsets II
方法一:枚举
思路,对于数组nums: [1,2,2,3]
最初,结果集res中只有空集,即res = [[]]
第1轮,将元素1加入到结果集中:res = [[], [1]]
第2轮,将元素2加入到结果集中:res= [[],[1], [2], [1,2]]
第3轮,接下来又是元素2,如果将复制之前的每个子集,再在复制的子集中加入元素2就会出现重复。即
res = [[], [1], [2], [1,2], [2], [1,2], [2, 2], [1,2,2]],其中红色的两个集合是重复的。即我们只能在已经出现元素2的集合中加入第二个2,形成不重复的子集。也就是说,只需要在加入了索引1处的元素2的两个子集中加入索引2处的元素2。可以在第2轮确定索引1处的元素加入到了几个子集(假设为n)中。第3轮只往这n个子集(位于结果集res的末尾处)中加入重复的元素2。
1 | class Solution { |
方法二: 回溯
如何在回溯过程中消除重复元素的影响?
1 | class Solution { |
参考文献
[1] Subsets 子集合: https://www.cnblogs.com/grandyang/p/4309345.html
[2] 含有重复元素的subsets子集: https://www.cnblogs.com/grandyang/p/4310964.html