题目
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
- 输入: [1,2,2]
- 输出:[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
方案一
思路: 主要是参照子集I解答,采用递归回溯法。重点在于如何去除重复的子集合。
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
//找到所有可能的方案,大部分使用搜锁,深度搜锁
//考点1:是否会写递归
//考点2:是否会去重{如果把所有的子集找出来再去重,时间复杂度会增加很多},如何加快运行降低时间复杂度
List<List<Integer>> ret = new ArrayList<>();
//Step1: 判断异常
if(nums == null || nums.length == 0) return ret;
//Step2:排序
Arrays.sort(nums);
//Step3:递归搜锁
List<Integer> subset = new ArrayList<>();//以subset开头的所有子集
subsetHelper(nums, 0, subset, ret);
//Step4:输出返回值
return ret;
}
//递归函数
private void subsetHelper(int[] nums, int startIndex,
List<Integer> subset, List<List<Integer>> ret){
//step3.1:将所得到的子集添加进结果中(克隆操作)
ret.add(new ArrayList<Integer>(subset));
//step3.2:
for(int i = startIndex; i < nums.length; i++){
//去重:判断nums[i] == nums[i-1] && i > startIndex
//访问数组时必须注意是否越界
if(i !=0 && nums[i] == nums[i-1] && i > startIndex){
continue;
}
subset.add(nums[i]);
subsetHelper(nums, i+1, subset, ret);
subset.remove(subset.size()-1);
}
}
}