力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

这题的两种做法:

1.递归法:

力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

递归法中最主要的思想是要弄懂 为什么可以用这种方法实现这道题;

通过从空集开始不断递归到集合中最后一个元素,

比如有数组[1,2,3] ,首先设置一个最终的大集合 力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 ;

因为空集是每个集合的子集,所以先把空集加入(这个算法的最重要的点) 此时大集合可以看作 [ [空集] ]

然后遍历数组[1,2,3]力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。,先从1开始,用1和空集合并为一个新的

子集[[1],[]]也就[1];(特别注意的是每次遍历一个数字后就复制一次用来拼接下一个元素)

此时大集合内的子集为[ [],[1] ];

复制一次用来遍历下一个元素力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

把数组里的第二个元素2拼接到复制来的数组中形成[[],[2]]和[ [1],[2] ]也就是[2]和[ [1],[2] ]

力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。通过addAll()方法把[2]和[ [1],[2] ]加入到大集合中,

此时大集合就为[  [], [1], [2], [[1],[2]],  ]

使用同上的方法把3也拼接到复制来的数组中得到[ [3], [1,3], [[1],[2],[3]] ],把他加入到大集合中就得到了最终子集和

[  [], [1], [2], [[1],[2]], [3], [1,3], [[1],[2],[3]] ]

 

2. 回溯法:

力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

回溯法最主要要明白的是backtrack方法的作用,因为回溯法是通过深度优先的方法来不断探索全部解,从中找出正确的解

backtrack方法中的k代表的是要找出子集的长度,子集的长度范围为num.length,所以只要力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。中for循环走完就可以找到所有子集;

力扣78题:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

然后看backtrack方法,当k==0时,代表构造的子集长度为0也就是空集,当k大于0时,比如k=1时

第一遍的时候k为1 ,开始位置start为0,也就是从[1,2,3]中的1开始,把[1]加入cur数组中(这里的cur充当工具人不断的重复利用来帮忙传递子集)

,然后到了下一步把 start+1,k-1; 这里start+1的目的是因为数组nums下标为0的元素已经放在了cur中,要+1从下一个元素开始,k-1是因为k代表构造子集的长度,既然已经加了一个元素,所以需要长度要减少1;这里因为k为1所有k-1后为0,所以可以直接加入大集合中;

然后cur.remove(cur.size()-1)的目的是为了让cur清除刚刚的数据更好的充当工具人;(这里有趣的是如果k的值够大,会多次从经过循环里的backtrack(无线套娃),当最终的backtrack走完时,上面的backtrack也会跟着走完,直到第一个,cur.remove()也会逐个执行,所以不用担心最后cur没有清除干净)