The solution of subset II could be easily derived from the answer of subset I.

Here is my answer of subset I:

```
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
res.add(new ArrayList<>());
for (int num: nums) {
List<List<Integer>> resDup = new ArrayList<>(res);
for (List<Integer> list:resDup) {
List<Integer> tmpList = new ArrayList<>(list);
list.add(num);
res.add(tmpList);
}
}
return res;
}
}
```

In this problem, we need to change two things:

- Sort the input nums, so that we won't get lists such as [1,4] and [4, 1] at the same time.
- Check duplicates when adding new list to res.

Here is Subset II solution based on subset I solution:

```
public class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
res.add(new ArrayList<Integer>());
Arrays.sort(nums); //important: sort nums
for (int num: nums) {
List<List<Integer>> resDup = new ArrayList<>(res);
for (List<Integer> list: resDup) {
List<Integer> tmp = new ArrayList<>(list);
tmp.add(num);
if (!res.contains(tmp)) //check duplicates
res.add(tmp);
}
}
return res;
}
}
```