首页 > 试题广场 >

集合的所有子集(二)

[编程题]集合的所有子集(二)
  • 热度指数:3072 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个整数数组 nums ,其中可能包含重复元素,请你返回这个数组的所有可能子集。

返回的答案中不能包含重复的子集,将答案按字典序进行排序。

数据范围:数组长度满足 ,数组中元素大小满足
示例1

输入

[1,2]

输出

[[],[1],[1,2],[2]]
示例2

输入

[1]

输出

[[],[1]]
要想答案按照字典序排列,我们要先对数组进行升序排列,然后再在这个有序数组上利用回溯法求子集。需要一个布尔数组来记录i位置的数是否已经被使用,从而达到去重的目的,当遇到相同的数时,如果前一个相同的数已经回溯过,那当前这个数就可以不考虑了。
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
        }
    }
}

发表于 2021-12-11 10:25:33 回复(0)
使用位运算枚举的解法
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @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


发表于 2024-04-17 22:39:10 回复(0)
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);
        }
    }
}

编辑于 2024-02-10 14:37:17 回复(0)
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();
        }
    }
}

编辑于 2024-01-29 15:44:28 回复(0)
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());
        }
    }
}

发表于 2023-08-26 11:57:44 回复(0)
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
}

发表于 2023-03-10 21:37:22 回复(0)
# -*- 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

发表于 2022-07-06 14:52:07 回复(0)
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @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
};
发表于 2022-04-24 12:15:35 回复(0)
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

编辑于 2022-04-12 07:06:53 回复(0)
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);
        }
    }
}


发表于 2021-12-07 10:49:19 回复(0)
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);
        }
    }
}

发表于 2021-12-03 20:16:40 回复(0)

问题信息

难度:
11条回答 2306浏览

热门推荐

通过挑战的用户

查看代码