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

集合的所有子集(二)

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,接着刚才的操作。

理解起来很难,加油。

全部评论

相关推荐

10-05 23:02
东北大学 Java
我说句实话啊:那时候看三个月培训班视频,随便做个项目背点八股,都能说3 40w是侮辱价
点赞 评论 收藏
分享
沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务