题目链接:
https://www.lintcode.com/problem/subsets-ii/description
给定一个可能具有重复数字的列表,返回其所有可能的子集。
样例 1:
输入:[0] 输出: [ [], [0] ]样例 2:
输入:[1,2,2] 输出: [ [2], [1], [1,2,2], [2,2], [1,2], [] ]你可以同时用递归与非递归的方式解决么?
思路:跟17题子集相类似。
在遍历数组时,判断当前元素是否出现过,没出现过,解法如17题。
若当前元素出现过,如{1,2,2,2},
遍历完第0、1个元素后,结果子集res为{{},{1},{2},{1,2}},
遍历第2个元素时发现,当前元素与第1个元素相等,则将当前加入{2}和{1,2}中变成{2,2}和{1,2,2},加入res,
res变成{{},{1},{2},{1,2},{2,2},{1,2,2}}
遍历第3个元素,遍历res时初始下标变了,res变成{{},{1},{2},{1,2},{2,2},{1,2,2},{2,2,2},{1,2,2,2}}
代码如下:
public class Solution { /** * @param nums: A set of numbers. * @return: A list of lists. All valid subsets. */ public List<List<Integer>> subsetsWithDup(int[] nums) { // write your code here List<List<Integer>> res = new ArrayList<>(); res.add(new ArrayList<>());
Arrays.sort(nums); int dup = 1; for(int i=0; i<nums.length; i++) { if(i-1>=0 &&nums[i]==nums[i-1]) { dup ++; }else{ dup = 1; } int resSize = res.size(); int startIndex = 0; if(dup>1) { startIndex = resSize/dup*(dup-1); } for(int j=startIndex; j<resSize; j++) { List<Integer> list = new ArrayList<>(res.get(j)); list.add(nums[i]); res.add(list); } } return res; } }