LCR 079. 子集
给定一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入: nums = [1,2,3]
输出: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入: nums = [0]
输出: [[],[0]]
提示:
1 <= nums.length <= 10-10 <= nums[i] <= 10nums中的所有元素 互不相同
解答:
方法一:递归+回溯
求组合,第一反应肯定是递归+回溯。问题就在怎么去构建递归和回溯,假设数组长度为n。求子集就是求出元素个数从0-n的所有不重复的组合个数。因为不能重复,简单起见,用一个set集合存储了所有的子集,最后再把set集合里面的数据放到List中再返回。遍历每种子集可能个数的情况,求出该元素个数下的子集。(这个方法虽然能过但是复杂度较高)
class Solution {
public List<List<Integer>> subsets(int[] nums) {
int n=nums.length;
Set<List<Integer>> res=new HashSet<>();
for(int i=0;i<=n;i++){
backTrack(nums,0,i,new ArrayList<Integer>(),res);
}
List<List<Integer>> result=new ArrayList<>();
for(List<Integer> ls:res){
result.add(ls);
}
return result;
}
public void backTrack(int[] nums, int index, int n, List<Integer> ls, Set<List<Integer>> res){
if(ls.size()==n){
res.add(new ArrayList<>(ls));
return;
}
if(index>=nums.length)
return;
ls.add(nums[index]);
backTrack(nums, index+1, n, ls, res);
ls.remove(ls.size()-1);
backTrack(nums,index+1,n, ls,res);
}
}
方法二:改进版本
太久没写回溯的题目了,写的好冗余啊,想得太复杂了,直接从第0个元素开始,往下添加或不添加这个元素进子集就可以了。因为每个元素值都是互不相同的。
class Solution {
public List<List<Integer>> subsets(int[] nums) {
int n=nums.length;
List<List<Integer>> res=new ArrayList<>();
backTrack(nums,0,new ArrayList<Integer>(), res);
return res;
}
public void backTrack(int[] nums, int index, List<Integer> ls, List<List<Integer>> res){
res.add(new ArrayList<>(ls));
if(index>=nums.length)
return;
for(int i=index;i<nums.length;i++){
ls.add(nums[i]);
backTrack(nums,i+1,ls,res);
ls.remove(ls.size()-1);
}
}
}