题目描述:
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
题解:
1、迭代法
public class L90 { public static List<List<Integer>> subsetsWithDup(int[] nums) { Arrays.sort(nums); List<List<Integer>> lists = new ArrayList<>(); /*维护一个列表,当当前元素与上一个元素相同的处理*/ List<List<Integer>> listOld = new ArrayList<>(); List<Integer> list = new ArrayList<>(); lists.add(list); for(int index = 0;index <nums.length;index++){ /*维护一个新的列表,用于添加新的元素*/ List<List<Integer>> lists02 = new ArrayList<>(); if(index >0 && nums[index] == nums[index-1]){ for(List<Integer> lis:listOld){ List<Integer> listNew = new ArrayList<>(lis); lists02.add(listNew); } }else { for(List<Integer> lis:lists){ List<Integer> listNew = new ArrayList<>(lis); lists02.add(listNew); } } for(List<Integer> li:lists02){ li.add(nums[index]); } listOld = new ArrayList<>(lists02); lists02.forEach(lis->lists.add(lis)); } return lists; } public static void main(String[] args) { int[] nums = {1,2,2}; List<List<Integer>> listss = subsetsWithDup(nums); }
2、回溯法
public class L90_1 { public static List<List<Integer>> subsetsWithDup(int[] nums) { Arrays.sort(nums); List<List<Integer>> lists = new ArrayList<>(); back_track(nums,lists,new Stack<Integer>(),0); return lists; } /*回溯法*/ public static void back_track(int[] nums, List<List<Integer>> lists, Stack<Integer> list, Integer index){ lists.add(new ArrayList<>(list)); for(int ii = index;ii<nums.length;ii++){ if(ii>index && nums[ii] == nums[ii-1]){continue;} list.push(nums[ii]); back_track(nums,lists,list,ii+1); list.pop(); } } public static void main(String[] args) { int[] nums = {1,2,2}; List<List<Integer>> listss = subsetsWithDup(nums); }