Given a list of numbers that may has duplicate numbers, return all possible subsets
Note
Each element in a subset must be in non-descending order.
The ordering between two subsets is free.
The solution set must not contain duplicate subsets.
Example
If S = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
class Solution {
/**
* @param S: A set of numbers.
* @return: A list of lists. All valid subsets.
*/
public ArrayList<ArrayList<Integer>> subsetsWithDup(ArrayList<Integer> S) {
// write your code here
ArrayList<ArrayList<Integer>> rst = new ArrayList<ArrayList<Integer>>();
if (S == null || S.size() == 0) {
return rst;
}
int[] num = new int[S.size()];
for (int i = 0; i < num.length; i++) {
num[i] = S.get(i);
}
ArrayList<Integer> set = new ArrayList<Integer>();
Arrays.sort(num);
helper(num, 0, set, rst);
return rst;
}
void helper(int[] num, int pos, ArrayList<Integer> set,
ArrayList<ArrayList<Integer>> rst) {
rst.add(new ArrayList(set));
for (int i = pos; i < num.length; i++) {
if (i > 0 && i > pos && num[i] == num[i - 1]) {
continue;
}
set.add(num[i]);
helper(num, i + 1, set, rst);
set.remove(set.size() - 1);
}
}
}
最开始做的时候[1,1] 的输出结果是:[[], [1]], expected output [[], [1], [1,1]]. 原因在于
<span style="color: rgb(113, 113, 113);"> for (int i = pos; i < num.length; i++) {
if (i > 0 && </span><span style="color:#ff0000;">i > pos</span><span style="color:#717171;"> && num[i] == num[i - 1]) {
continue;
}
set.add(num[i]);
helper(num, i + 1, set, rst);
set.remove(set.size() - 1);
}</span>
写的是
for (int i = pos; i < num.length; i++) {
if (i > 0 && num[i] == num[i - 1]) {
continue;
}
set.add(num[i]);
helper(num, i + 1, set, rst);
set.remove(set.size() - 1);
}
那么当第一个数取出了1, 第二个数理解为在level2, 它就取不到1了,我们想要的逻辑是:同一层不能取一样的数,但是不同层之间可以取一样的数,因此需要加上i > pos.
这题的整体逻辑是:
[1,1,2,2,3,3,4,4,5]对于这个input,同样的数我们取第一个能得到最多的子集,比如对于2,我们取第一个2能打印出2233445, 但如果取第二个2就只能打印出11233445,所以在同一层我们取相同数的第一个。