/**
* https://leetcode-cn.com/problems/subsets-ii/
* 不能包含重复的子集
* 思路:
* 构造一个对应关系
* key为数字,value为该数字的个数
* 决策树,不选,该数字的个数从0到value个
* 不再是选或者是不选,而是不选或者是选几个
* @param nums
* @return
*/
public List<List<Integer>> subDupList = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
//构造对应关系
Map<Integer, Integer> hashMap = new HashMap<>();
for (int i = 0; i < nums.length; i++){
if (hashMap.containsKey(nums[i])){
Integer count = hashMap.get(nums[i]);
hashMap.put(nums[i], count+1);
} else {
hashMap.put(nums[i], 1);
}
}
//构造两个数组,一个用于存储数据,一个用于存储数量
int n = hashMap.size();
int[] uniqueNums = new int[n];
int[] counts = new int[n];
int k = 0;
for (int i = 0; i < nums.length; i++){
if (hashMap.containsKey(nums[i])){
uniqueNums[k] = nums[i];
counts[k] = hashMap.get(nums[i]);
k++;
hashMap.remove(nums[i]);
}
}
backtrackSubsetdup(uniqueNums, counts, 0, new ArrayList<>());
return subDupList;
}
public void backtrackSubsetdup(int[] uniqueNums, int[] counts, int k, List<Integer> path){
if (k == uniqueNums.length){
subDupList.add(new ArrayList<>(path));
return;
}
for (int i = 0; i <= counts[k]; i++){
// for (int i = 0; i < counts[k]; i++){
//选i次,依次放入i个,即循环从0->i
for (int m = 0; m < i; m++){
path.add(uniqueNums[k]);
}
//选择下一个
backtrackSubsetdup(uniqueNums, counts, k+1, path);
//回退,放几个,则回退几个,回退的方式也是循环从0到
for (int m = 0; m < i; m++){
path.remove(path.size()-1);
}
}
}
回溯-子集-不能包含重复的子集
最新推荐文章于 2023-12-07 16:35:39 发布