题目描述
给你一个整数数组 nums,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例 1:
输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
扩展法(时间复杂度为O(N*(2^N)),空间复杂度为O(1))
java实现
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res=new ArrayList<>();
res.add(new ArrayList<>());
Arrays.sort(nums);
for(int i=0;i<nums.length;i++)
{
int resLength=res.size();
for(int j=0;j<resLength;j++)
{
List<Integer> cur=new ArrayList<>(res.get(j));
cur.add(nums[i]);
res.add(cur);
}
}
HashSet<List<Integer>> set=new HashSet<>(res);
return new ArrayList<>(set);
}
}
Python实现
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res=[[]]
nums.sort()
for num in nums:
res+=[i+[num] for i in res if i+[num] not in res]
return res
回溯法(时间复杂度为O(N*(2^N)),空间复杂度为O(N*(2^N)))
java实现
import java.util.Arrays;
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res=new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length+1;i++)
{
//get the backtracking length
backtracking(nums,i,0,res,new ArrayList<>());
}
return res;
}
private void backtracking(int[] nums,int len,int startIndex,List<List<Integer>> res,List<Integer> cur)
{
if(cur.size()==len)
{
res.add(new ArrayList<>(cur));
return;
}
for(int i=startIndex;i<nums.length;i++)
{
if(i>startIndex&&nums[i]==nums[i-1])
{ continue; }
cur.add(nums[i]);
backtracking(nums,len,i+1,res,cur);
cur.remove(cur.size()-1);
}
}
}
Python实现
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res=[]
nums.sort()
for i in range(len(nums)+1):
self.backtracking(nums,i,0,[],res)
return res
def backtracking(self,sorted_nums:List[int],length:int,index:int,cur,res):
if len(cur)==length:
res.append(cur[:])
return
for i in range(index,len(sorted_nums)):
if i>index and sorted_nums[i]==sorted_nums[i-1]:
continue
cur.append(sorted_nums[i])
self.backtracking(sorted_nums,length,i+1,cur,res)
cur.pop()
DFS深度优先算法(时间复杂度为O(N*(2^N)),空间复杂度为O(1))
java实现
import java.util.Arrays;
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res=new ArrayList<>();
Arrays.sort(nums);
dfs(nums,0,res,new ArrayList<>());
return res;
}
private void dfs(int[] nums,int startIndex,List<List<Integer>> res,List<Integer> cur)
{
res.add(new ArrayList<>(cur));
for(int i=startIndex;i<nums.length;i++)
{
if(i>startIndex&&nums[i]==nums[i-1])
{ continue; }
cur.add(nums[i]);
dfs(nums,i+1,res,cur);
cur.remove(cur.size()-1);
}
}
}
Python实现
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res=[]
nums.sort()
self.dfs(nums,[],res)
return res
def dfs(self,sorted_nums,cur,res):
res.append(cur)
for i in range(len(sorted_nums)):
if i>0 and sorted_nums[i]==sorted_nums[i-1]:
continue
self.dfs(sorted_nums[i+1:],cur+[sorted_nums[i]],res)