又一个backtrack的典型。
这次里面有重复的数字了。
就看怎么跳过重复的数字。
public class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums)
{
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(nums.length == 0) return res;
Arrays.sort(nums);
helper(res,nums,new ArrayList<Integer>(),0);
return res;
}
public void helper(List<List<Integer>> res, int[] nums, List<Integer> tempList,int m)
{
res.add(new ArrayList<Integer>(tempList));
if(m == nums.length)
{
return;
}
else
{
for(int i = m; i < nums.length;i++)
{
if(i != m && nums[i] == nums[i-1]) continue;
tempList.add(nums[i]);
helper(res,nums,new ArrayList<Integer>(tempList),i+1);
tempList.remove(tempList.size()-1);
}
}
}
}
具体用来跳过的是
if(i != m && nums[i] == nums[i-1]) continue;
具体点是,一次for loop里,重复的数只能用一次。
比如2 2 2来说
for(int i = 0; i < 3; i++)
第一个是2,进入下一层,i < 2,当前是22,进入下一层,i<1,当前是222。
第二个是2,跟第一个一样,这次LOOP里再出现2都不添加了,所以直接看第三个,第三个恰好也是2,所以看第4个,没第4个,结束。
这个就属于解释比较麻烦,但是思考起来很容易……
三刷。
也是比较典型的DFS+backtracking
区别是有重复元素,所以构建并进入下一层的时候需要判断是否是重复元素。
也可以理解为,回溯之后,如果下一个元素跟当前元素相等,就跳过。
Time: O(n * 2^n)
Space: O(n)
public class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Arrays.sort(nums);
dfs(res, nums, 0, new ArrayList<>());
return res;
}
public void dfs(List<List<Integer>> res, int[] nums, int m, List<Integer> tempList) {
res.add(new ArrayList<>(tempList));
for (int i = m; i < nums.length; i++) {
if (i != m && nums[i] == nums[i-1]) continue;
tempList.add(nums[i]);
dfs(res, nums, i+1, new ArrayList<>(tempList));
tempList.remove(tempList.size()-1);
}
}
}
iteratively..:
唯一的区别还是重复,遇到二次出现,上一轮添加过的子集就不用再添加的,比如1 2 3 4 5 6 6
第一个6添加的时候前面1-5都来过一次了,第二个6按理说应该是1-6,但是前1-5重复了,就不需要了,直接从前一个6开始就行了,因为前1个6并没有添加自己= =。。
public class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
res.add(new ArrayList<>());
Arrays.sort(nums);
int start = 0;
for (int i = 0; i < nums.length; i++) {
int total = res.size();
for (int j = start; j < total; j++) {
List<Integer> tempList = new ArrayList<>(res.get(j));
tempList.add(nums[i]);
res.add(tempList);
}
if (i != nums.length - 1 && nums[i] == nums[i+1]) start = total;
else start = 0;
}
return res;
}
}