题解 | #集合的所有子集(二)#

集合的所有子集(二)

https://www.nowcoder.com/practice/a3dfd4bc8ae74fad9bc65d5ced7ae813

import java.util.*;


public class Solution {
    ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    int n;
    ArrayList<Integer> path = new ArrayList<>();
    boolean[] used = new boolean[n];
    public ArrayList<ArrayList<Integer>> subsets (int[] nums) {
        Arrays.sort(nums);
        n = nums.length;
        for (int i = 0; i <= n; i++) {
            dfs(0, i, nums);
        }
        res.sort(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                ArrayList<Integer> o11 = (ArrayList<Integer>) o1;
                ArrayList<Integer> o12 = (ArrayList<Integer>) o2;
                int i = 0;
                int j = 0;
                while (i < o11.size() || j < o12.size()) {
                    int x = Integer.MIN_VALUE;
                    int y = Integer.MIN_VALUE;
                    if (i == o11.size()) {
                        y = o12.get(j);
                        i++;
                    } else if (j == o12.size()) {
                        x = o11.get(i);
                        j++;
                    } else {
                        x = o11.get(i);
                        y = o12.get(j);
                        i++;
                        j++;
                    }
                    if (x > y) return 1;
                    if (x < y) return -1;
                }
                return 0;
            }
        });
        return res;
    }

    void dfs(int start, int k, int[] nums) {
        if (k == 0) {
            res.add(new ArrayList<>(path));
            return;
        }

        for (int i = start; i < n; i++) {
            if (i > start && nums[i - 1] == nums[i]) continue;
            path.add(nums[i]);
            dfs(i + 1, k - 1, nums);
            path.remove(path.size() - 1);
        }
    }
}

我用的是经典模板,更好理解,这里稍微麻烦的是需要传入一个comparator比较器,因为牛客需要按字典序输出。

题的执行过程:

我需要获得长度为0到n的子集序列,先从0开始,如果此时所需寻找的子集长度为0,添加到结果集,

然后寻找长度为1的子集序列,start下标在每次寻找时都要加一,保证子集不会回头去找。

去重的话,使用i>start和nums[i] == nums[i-1] continue 来保证不会有重复的。

举个例子: 1 2 2

先找子集个数为0的,此时需要的子集个数为0,return。

再找子集个数为1的,传入start=0, k = 1, 表示从第一个开始取数,此时需要的子集个数为1,找到之后,加入path,k-1;

此时k=0,将它加入到结果集。

循环,从 下标一开始,如果与前一个相同,则会重复,所以continue,接着刚才的操作。

理解起来很难,加油。

全部评论

相关推荐

头像
不愿透露姓名的神秘牛友
04-08 00:50
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务