面试题 08.04. 幂集
解题思路
首先,定义了一个空的列表 ans 用于存储最终的结果。然后,通过 ans.add(new ArrayList()) 将一个空列表添加到 ans 中,表示空集。
接下来,调用 getSets 函数来生成所有的子集。getSets 函数接受四个参数:结果列表 ans、当前处理的索引 i、给定数组 nums。
在 getSets 函数中,首先判断递归结束的条件,即 i 等于数组长度 nums.length,此时直接返回。
然后,创建一个辅助列表 help,将 ans 中的所有列表复制到 help 中。这是因为在遍历 help 的过程中,我们要同时向 ans 中添加新的列表,如果直接在 ans 上进行遍历和修改,会导致遍历过程中的无限循环。
接下来,对于 help 中的每个列表 E,创建一个新的列表 t,将 E 中的所有元素复制到 t 中,然后将当前处理的数字 nums[i] 添加到 t 中,表示在当前的子集中加入这个数字。
最后,将 t 添加到 ans 中,表示将新生成的子集加入到结果列表中。
然后,递归调用 getSets 函数,将 i 的值加一,继续生成下一个位置的子集。
最终,在主函数中调用 getSets 函数后,返回 ans 列表,其中包含了给定数组 nums 的所有子集。
class Solution {
public List<List<Integer>> subsets(int[] nums) {
// 创建新的List
List<List<Integer>> ans = new ArrayList<>();
// 首先将空集合 加入集合中
ans.add(new ArrayList<Integer>());
// 将其他元素集合加入其中
getSets(ans,0,nums);// 递归操作 生成nums的所有子集
return ans;
}
public void getSets(List<List<Integer>> ans, int i,int[] nums){
// 递归结束条件 i等于数组长度 nums.length
if(i == nums.length){
return;
}
List<List<Integer>> help = new ArrayList<>(ans);// 将原来的ans中的所有子集合 全部加入现在的集合中
// 取出所有的集合
for(List<Integer> E:help){
// 创建一个新的集合 使用E中的全部元素
List<Integer> t = new ArrayList<Integer>(E);
// 将元素添加到集合中
t.add(nums[i]);// 添加元素 将元素i添加到集合
ans.add(t);// 然后ans 将新的子集 添加进入该集合
}
getSets(ans,i + 1,nums);// 接着进行递归
}
}