版权声明:版权所有,转载请注明原网址链接。 https://blog.csdn.net/qq_41231926/article/details/83067781
我的LeetCode代码仓:https://github.com/617076674/LeetCode
原题链接:https://leetcode-cn.com/problems/subsets-ii/description/
题目描述:
知识点:递归、回溯
思路:回溯法寻求所有组合
本题和LeetCode078——子集的解法几乎相同。只不过本题中的整数数组nums会可能包含有重复元素。
对于重复元素的处理,我们只需要用一个哈希表来代替数组即可。在回溯过程中,确保新加入的元素的值不会大于list中的最后一个元素的值,这样可以防止{1, 2}和{2, 1}这样的重复集合出现。这其实是一个剪枝操作。
时间复杂度和空间复杂度均是O(2 ^ n)级别的,其中n为nums数组的长度。
JAVA代码:
public class Solution {
private List<List<Integer>> listList;
public List<List<Integer>> subsetsWithDup(int[] nums) {
listList = new ArrayList<>();
HashMap<Integer, Integer> hashMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
addToHashMap(hashMap, nums[i]);
}
for (int i = 0; i <= nums.length; i++) {
subsetsWithDup(new ArrayList<>(), i, hashMap);
}
return listList;
}
private void subsetsWithDup(List<Integer> list, int n, HashMap<Integer, Integer> hashMap){
if(list.size() == n){
if(!listList.contains(list)) {
listList.add(new ArrayList<>(list));
}
return;
}
HashMap<Integer, Integer> tempHashMap = new HashMap<>(hashMap);
for(Integer temp : tempHashMap.keySet()){
if(!list.isEmpty() && list.get(list.size() - 1) > temp){
continue;
}
list.add(temp);
delFromHashMap(hashMap, temp);
subsetsWithDup(list, n, hashMap);
addToHashMap(hashMap, temp);
list.remove(list.get(list.size() - 1));
}
}
private void addToHashMap(HashMap<Integer, Integer> hashMap, Integer temp){
if(hashMap.containsKey(temp)){
hashMap.put(temp, hashMap.get(temp) + 1);
}else{
hashMap.put(temp, 1);
}
}
private void delFromHashMap(HashMap<Integer, Integer> hashMap, Integer temp){
hashMap.put(temp, hashMap.get(temp) - 1);
if(hashMap.get(temp) == 0){
hashMap.remove(temp);
}
}
}
LeetCode解题报告: