您的位置:首页 > 其它

Leetcode 题解 - 搜索--Backtracking(20):含有相同元素求子集

2019-05-28 15:46 288 查看

[LeetCode] Subsets II 子集合之二

 

Given a collection of integers that might contain duplicates, S, return all possible subsets.

Note:

  • Elements in a subset must be in non-descending order.
  • The solution set must not contain duplicate subsets.

 

For example,
If S = 

[1,2,2]
, a solution is:

[code][
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]

 与上一题唯一的区别在于:要去重,去重写法已经写了无数遍了 但是记住这种写法的前提是数组是有序数组,你重复的数值是连续排列的,不然并不能去掉重复的结果

 

[code]class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> subset = new ArrayList<>();
List<Integer> subsetList = new ArrayList<>();
boolean[] visited = new boolean[nums.length];
for(int i=0; i <= nums.length; i++)
help(subset, subsetList, visited, 0, i, nums);
return subset;
}
private void help(List<List<Integer>> subset, List<Integer> subsetList,
boolean[] visited, int start, final int size, final int[] nums){
if(subsetList.size() == size){
subset.add(new ArrayList<>(subsetList));
return;
}

for(int i = start; i < nums.length; i++){
if(i != 0 && nums[i] == nums[i - 1] && !visited[i - 1])
continue;
visited[i] = true;
subsetList.add(nums[i]);
help(subset, subsetList, visited, i + 1, size, nums);
subsetList.remove(subsetList.size() - 1);
visited[i] = false;
}
}
}

第二次写

与之前的区别是每次设置size改成每次都添加而已

[code]class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> list = new ArrayList<>();
Arrays.sort(nums);
result.add(new ArrayList());
boolean[] visited = new boolean[nums.length];
help(list, result, nums, 0, visited);
return result;
}
private void help(List<Integer> list, List<List<Integer>> result, int[] nums, int start,
boolean[] visited){

for(int i = start; i < nums.length; i++){
if(i >= 1 && nums[i] == nums[i-1] && !visited[i-1])
continue;
visited[i] = true;
list.add(nums[i]);
if(list.size() <= nums.length)
result.add(new ArrayList(list));
help(list, result, nums, i+1, visited);
list.remove(list.size() - 1);
visited[i] =false;
}
}
}

换个写法 都一样 方便理解整个回溯调用的过程

[code]​
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> list = new ArrayList<>();
Arrays.sort(nums);
// result.add(new ArrayList());
boolean[] visited = new boolean[nums.length];
help(list, result, nums, 0, visited);
return result;
}
private void help(List<Integer> list, List<List<Integer>> result, int[] nums, int start,
boolean[] visited){
if(list.size() <= nums.length){
result.add(new ArrayList(list));
}
for(int i = start; i < nums.length; i++){
if(i >= 1 && nums[i] == nums[i-1] && !visited[i-1])
continue;
visited[i] = true;
list.add(nums[i]);
// if(list.size() <= nums.length)
//     result.add(new ArrayList(list));
help(list, result, nums, i+1, visited);
list.remove(list.size() - 1);
visited[i] =false;
}
}
}

​

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐