给定一个整数数组 nums ,其中可能包含重复元素,请你返回这个数组的所有可能子集。
返回的答案中不能包含重复的子集,将答案按字典序进行排序。
数据范围:数组长度满足
,数组中元素大小满足 
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型二维数组
*/
ArrayList<ArrayList<Integer>> results = new ArrayList<>();
public ArrayList<ArrayList<Integer>> subsets (int[] nums) {
// write code here
Arrays.sort(nums);
boolean[] used = new boolean[nums.length];
dfs(nums, 0, new ArrayList<Integer>(), used);
return results;
}
private void dfs(int[] nums, int depth, ArrayList<Integer> result, boolean[] used) {
results.add(new ArrayList<Integer>(result));
for(int i = depth; i < nums.length; i++){
if(i > 0 && nums[i - 1] == nums[i] && !used[i - 1]) continue; // 上一个相同的数已经回溯过了,跳过
result.add(nums[i]);
used[i] = true;
dfs(nums, i + 1, result, used);
result.remove(result.size() - 1);
used[i] = false; // 回溯完后状态会被改成false
}
}
} public static ArrayList<ArrayList<Integer>> subsets(int[] nums) {
// write code here
Arrays.sort(nums); // 元素位置可颠倒
int subLen = (int) Math.pow(2, nums.length);
PriorityQueue<ArrayList<Integer>> priorityQueue = new PriorityQueue<>(
(o1, o2) -> {
StringBuilder o1Sb = new StringBuilder();
StringBuilder o2Sb = new StringBuilder();
for (Integer o1e : o1) o1Sb.append(o1e);
for (Integer o2e : o2) o2Sb.append(o2e);
return o1Sb.toString().compareTo(o2Sb.toString());
});
for (int i = 0; i < subLen; i++) {
String s = Integer.toBinaryString(i);
ArrayList<Integer> subList = new ArrayList<>();
for (int j = 0; j < s.length(); j++)
if (s.charAt(s.length() - j - 1) == '1')
subList.add(nums[j]);
priorityQueue.add(subList);
}
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
while (!priorityQueue.isEmpty()) {
ArrayList<Integer> poll = priorityQueue.poll();
if (!res.isEmpty() && res.get(res.size() - 1).equals(poll))
continue;
res.add(poll);
}
return res;
}
public static ArrayList<ArrayList<Integer>> subsetsTraceback(int[] nums) {
Arrays.sort(nums);// 排序是因为题目需要字典序顺序
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
res.add(new ArrayList<>());// 空集合
helper(nums, 0, res, new ArrayList<>());
return res;
}
public static void helper(int[] nums, int pos,
ArrayList<ArrayList<Integer>> res, List<Integer> cur) {
for (int i = pos; i < nums.length; i++) {
cur.add(nums[i]); // 为了字典序, 先加入再递归
if (!res.contains(cur)){ // 递归和回溯时不同深度栈帧和不同i会有大量重复,需判断去重
res.add(new ArrayList<>(cur));// 先把当前子集加入结果集
helper(nums, i + 1, res, cur); // 继续找比当前大的字典序子集
}
cur.remove(cur.size() - 1);//当前的元素处理完毕,尝试其他, 回溯
}
} # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param nums int整型一维数组 # @return int整型二维数组 # class Solution: def subsets(self , nums: List[int]) -> List[List[int]]: # write code here s = set() nums.sort() count = pow(2, len(nums)) for i in range(count): b = bin(i)[2:] tmp = [] for j in range(len(nums)-len(b), len(nums)): if b[j-(len(nums)-len(b))] == '1': tmp.append(nums[j]) s.add(tuple(tmp)) res = list(s) res.sort() return res
vector<vector<int> > subsets(vector<int>& nums) {
// write code here
set<vector<int>> res = {{}}; // 初始包含空集
for (int num : nums) {
set<vector<int>> temp = res; // 复制当前所有子集
for (auto subset : temp) { // 遍历每个已有子集
subset.push_back(num); // 添加当前元素
sort(subset.begin(), subset.end());
res.insert(subset); // 添加新生成的子集
}
}
vector<vector<int>> result;
for (auto r : res) {
result.push_back(r);
}
return result;
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型ArrayList<ArrayList<>>
*/
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
ArrayList<Integer> path = new ArrayList<>();
public ArrayList<ArrayList<Integer>> subsets (int[] nums) {
// write code here
// 回溯
Arrays.sort(nums);
backtracing(0, nums);
return res;
}
private void backtracing(int start, int[] nums) {
res.add(new ArrayList<>(path));
for(int i = start; i < nums.length; i++) {
// 层内去重
if((i != start) && (nums[i] == nums[i - 1])) continue;
path.add(nums[i]);
backtracing(i + 1, nums);
path.remove(path.size() - 1);
}
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型ArrayList<ArrayList<>>
*/
ArrayList<ArrayList<Integer>> result=new ArrayList<>();
LinkedList<Integer> path=new LinkedList<>();
public ArrayList<ArrayList<Integer>> subsets (int[] nums) {
// write code here
Arrays.sort(nums);
backtracking(nums,0);
return result;
}
void backtracking(int[] nums,int start){
result.add(new ArrayList<>(path));
for(int i=start;i<nums.length;i++){
if(i>start&&nums[i-1]==nums[i])continue;
path.add(nums[i]);
backtracking(nums,i+1);
path.removeLast();
}
}
} public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型ArrayList<ArrayList<>>
*/
private ArrayList<ArrayList<Integer>> result = new ArrayList<>();
private Deque<Integer> path = new LinkedList<>();
public ArrayList<ArrayList<Integer>> subsets (int[] nums) {
Arrays.sort(nums);
boolean[] used = new boolean[nums.length];
backTracking(nums, 0, used);
Collections.sort(result, new CustomComparator());
return result;
}
private void backTracking(int[] nums, int index, boolean[] used) {
result.add(new ArrayList<>(path));
for (int i=index; i<nums.length; i++) {
if (i > 0 && used[i-1] == false && nums[i] == nums[i-1]) continue;
used[i] = true;
path.offer(nums[i]);
backTracking(nums, i+1, used);
path.pollLast();
used[i] = false;
}
}
private static class CustomComparator implements Comparator<ArrayList<Integer>> {
public int compare(ArrayList<Integer> a, ArrayList<Integer> b) {
//if (a.isEmpty()) return 1;
//if (b.isEmpty()) return -1;
StringBuilder str1 = new StringBuilder();
StringBuilder str2 = new StringBuilder();
for (int e: a) str1.append(e);
for (int e: b) str2.append(e);
return str1.toString().compareTo(str2.toString());
}
}
} package main
import "sort"
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型二维数组
*/
func subsets( nums []int ) [][]int {
sort.Ints(nums)
ans:=[][]int{}
var dfs func([]int,int)
dfs=func(path []int,idx int){
tmp:=make([]int,len(path))
copy(tmp,path)
ans=append(ans,tmp)
for i:=idx;i<len(nums);i++{
if i>idx&&nums[i]==nums[i-1]{
continue
}
path=append(path,nums[i])
dfs(path,i+1)
path=path[:len(path)-1]
}
}
dfs([]int{},0)
return ans
} # -*- coding: utf-8 -*- # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param nums int整型一维数组 # @return int整型二维数组 # class Solution: """ 题目: 集合的所有子集(二) https://www.nowcoder.com/practice/a3dfd4bc8ae74fad9bc65d5ced7ae813?tpId=117&&tqId=39446&rp=1&ru=/ta/job-code-high&qru=/ta/job-code-high/question-ranking 参考: 大神:代码界的小白 https://leetcode.cn/problems/sliding-window-median/solution/hua-dong-chuang-kou-zhong-wei-shu-by-lee-7ai6/ 算法: 题目要求:寻找nums的所有子集,结果按字典序排序 1. 对nums进行排序 2. 定义回溯函数dfs(combine, idx),初始combine为[],idx为0。 a. 记录子集combine b. 枚举可选元素,加入combine,从下一个下标继续搜索;搜索完毕,回溯 复杂度: 时间复杂度:O(nlogn + n * 2^n) = O(n * 2^n),排序算法的复杂度:O(nlogn),构造子集:共2^n种状态,每种状态需要O(n)复杂度构造子集,构造子集的总复杂度为O(n * 2^n) 空间复杂度:O(n),临时数组combine """ def subsets(self, nums): # write code here def dfs(combine, idx): res.append(combine[:]) for i in range(idx, n): if i > idx and nums[i] == nums[i - 1]: # 剪枝:前一个相同的数已经回溯了 continue combine.append(nums[i]) dfs(combine, i + 1) combine.pop() nums.sort() res, n = [], len(nums) dfs([], 0) return res if __name__ == '__main__': s = Solution() # nums = [1, 2] # nums = [1] nums = [1, 1, 1] # nums = [3, 6, 7, 5] res = s.subsets(nums) print res
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型二维数组
*/
let result=[],path=[],visited=[];
function subsets( nums ) {
// write code here
nums.sort(function(a,b){
return a-b;
})
backTrace(nums,nums.length,0);
return result;
}
function backTrace(n,k,start){
result.push([...path]);
for(let i=start;i<k;i++){
// 增加访问标记visited,避免[1,1,1] 重复元素重复添加
if(i>start && n[i]==n[i-1]) continue; // 满足条件继续
// if(i > 0 && n[i]==n[i-1] && !visited[i-1]) continue;
path.push(n[i]);
// visited[i]=1; // 节点被访问
backTrace(n,k,i+1);
path.pop();
// visited[i]=0; // 节点访问标记置0
}
}
module.exports = {
subsets : subsets
};
class Solution:
def subsets(self , nums: List[int]) -> List[List[int]]:
# write code here
if len(nums)<=1:
return [nums]
res=[]
nums.sort()
def backtrace(start,path):
res.append(path)
add=set()
for i in range(start,len(nums)):
if nums[i] not in add:
add.add(nums[i])
cur_path=path+[nums[i]]
backtrace(1+i, cur_path)
backtrace(0,[])
#res.sort()
return res import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型二维数组
*/
ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();
//HashSet<ArrayList<Integer>> set = new HashSet<ArrayList<Integer>>();
public ArrayList<ArrayList<Integer>> subsets (int[] nums) {
// write code here
ArrayList<Integer> list = new ArrayList<>();
//ans.add(list);
Arrays.sort(nums);
dfs(nums, 0, list);
return ans;
}
public void dfs(int[] nums, int start, ArrayList<Integer> list){
if(!ans.contains(list)){
ans.add(new ArrayList<Integer>(list));
}
for(int i=start;i<nums.length;i++){
list.add(nums[i]);
dfs(nums, i+1, list);
list.remove(list.size()-1);
}
}
} import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型二维数组
*/
ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
List<Integer> list = new LinkedList<>();
public ArrayList<ArrayList<Integer>> subsets (int[] nums) {
// write code here
Arrays.sort(nums);
dfs(nums,0);
return ans;
}
void dfs(int[] nums, int index){
ans.add(new ArrayList(list));
for(int i =index; i < nums.length; i++){
if(i > index && nums[i] == nums [i-1]) {
continue;
}
list.add(nums[i]);
dfs(nums,i+1);
list.remove(list.size() - 1);
}
}
}