// 1. 确定子集,首先要有开始位置,startIndex;返回值void
    // 2. 递归终结:存储每一个path,然后return即可
    // 3. 单层逻辑:因为要返回子集,所以只要存储每一个path就好呀

import java.util.*;

public class Solution {
    private ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
    private LinkedList<Integer> path = new LinkedList<Integer>();

    public ArrayList<ArrayList<Integer>> subsets(int[] S) {
        // 1. 确定子集,首先要有开始位置,startIndex;返回值void
        // 2. 递归终结:存储每一个path,然后return即可
        // 3. 单层逻辑:因为要返回子集,所以只要存储每一个path就好呀
        Arrays.sort(S);
        getSub(S, 0);
        res.sort(Comparator.comparingInt(ArrayList::size));
        return res;
    }

    private void getSub(int[] S, int startIndex) {
        res.add(new ArrayList(path));

        for (int i = startIndex; i < S.length; ++i) {
            path.add(S[i]);
            getSub(S, i + 1);
            path.removeLast();
        }
    }
}