题目描述
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
思路
回溯模板
backtrack(路径, 选择列表){
if (满足结束条件)
result.add(路径)
return
for (选择 in 选择列表)
做选择
backtrack(路径, 选择列表)
撤销选择
}
遍历整个数组,递归得到以每个元素为起始数字的所有子集。
以[1,2,3]为例,先求出以1开头的所有子集,然后是2开头的所有子集,最后是3。
要用 index参数排除已选择的数字,例如当拿到以1开头的所有子集,index指向2,再也不会拿到元素1了。
递归结束标志:当标记递归深度的变量等于数组的长度
90.子集 II 与78题的区别是需要去重,先数组排序,若当前值与它前面的值相同且当前值不是起始数字,这种情况跳过当前值即可避免重复。画图方便理解。
78.子集代码:
import java.util.List;
import java.util.ArrayList;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList();
res.add(new ArrayList());
backtrace(nums,0,res,new ArrayList());
return res;
}
public void backtrace(int[] nums, int index, List<List<Integer>> res, List<Integer> li){
if(index == nums.length){
return;
}
for(int i = index; i < nums.length; i++){
li.add(nums[i]);
res.add(new ArrayList(li));
backtrace(nums,i+1,res,li);
li.remove(li.size()-1);
}
}
}
90.子集 II代码
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList();
res.add(new ArrayList());
Arrays.sort(nums);
backtrace(nums,0,res,new ArrayList());
return res;
}
public void backtrace(int[] nums, int index, List<List<Integer>> res, List<Integer> li){
if(index == nums.length){
return;
}
for(int i = index; i < nums.length; i++){
if(i > index && nums[i-1] == nums[i]){
continue;
}
li.add(nums[i]);
res.add(new ArrayList(li));
backtrace(nums,i+1,res,li);
li.remove(li.size()-1);
}
}
}