LeetCode – Subsets (Java)

Given a set of distinct integers, S, return all possible subsets.

Note: 1) Elements in a subset must be in non-descending order. 2) The solution set must not contain duplicate subsets.

For example, given S = [1,2,3], the method returns:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

Thoughts

Given a set S of n distinct integers, there is a relation between Sn and Sn-1. The subset of Sn-1 is the union of {subset of Sn-1} and {each element in Sn-1 + one more element}. Therefore, a Java solution can be quickly formalized.

Java Solution

public ArrayList<ArrayList<Integer>> subsets(int[] S) {
	if (S == null)
		return null;
 
	Arrays.sort(S);
 
	ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
 
	for (int i = 0; i < S.length; i++) {
		ArrayList<ArrayList<Integer>> temp = new ArrayList<ArrayList<Integer>>();
 
		//get sets that are already in result
		for (ArrayList<Integer> a : result) {
			temp.add(new ArrayList<Integer>(a));
		}
 
		//add S[i] to existing sets
		for (ArrayList<Integer> a : temp) {
			a.add(S[i]);
		}
 
		//add S[i] only as a set
		ArrayList<Integer> single = new ArrayList<Integer>();
		single.add(S[i]);
		temp.add(single);
 
		result.addAll(temp);
	}
 
	//add empty set
	result.add(new ArrayList<Integer>());
 
	return result;
}

10 thoughts on “LeetCode – Subsets (Java)”

  1. “`
    public ArrayList<ArrayList> get(int[] input) {
    ArrayList<ArrayList> result = new ArrayList();

    result.add(new ArrayList(Arrays.asList(input[0])));

    for (int i = 1; i < input.length; i++) {
    int curr = input[i];
    int size = result.size();
    result.add(new ArrayList(Arrays.asList(curr)));
    for (int j = 0; j < size; j++) {
    ArrayList temp = new ArrayList();
    temp.addAll(result.get(j));
    temp.add(curr);
    result.add(temp);
    }
    }

    return result;
    }
    “`

  2. Collections.sort(result, new Comparator<ArrayList>() {
    @Override
    public int compare(ArrayList a, ArrayList b) {
    int an = a.size();
    int bn = b.size();
    for (int i = 0; i < Math.min(an, bn); i++) {
    int cmp = Integer.compare(a.get(i), b.get(i));
    if (cmp != 0)
    return cmp;
    }
    return Integer.compare(a.size(), b.size());
    }
    });

    it will work fine now.

  3. the code will give sets in unsorted form, we also have to write a modified comparable func to compare the final sets of result list by comparing first elements of every two sets .

  4. if you designate each element in the array with 0 or 1 (not-present/present), then all possible combinations of binary number with 3 positions is 2^3=8. For n position it is 2^n. Nothing to induct more mathematically other than that.

  5. actually I wouldn’t go the master theorem way, because for that the ‘aT(n/b)’ term needs to be defined, here a_n = 2a_(n-1) + f(n).. its hard to visualize it in terms of T(n/b), i would simply explain it as for every element i: work done = 2*2^(i-1) [using a_n=2*a_(n-1)] so for a^n=2^n, base case a_0=1 (considering 0 elements, empty subset)

  6. Much simpler in Scala

    def allSubsets(S: List[Int]) = {
    S.distinct.sorted.foldLeft(List(List.empty[Int])) { (subsets, num) ⇒
    subsets ++ subsets.map(_ :+ num)
    }
    }

  7. I know the time complexity is 2 power n, how do i get there with a mathematical formula? anyone please?, i was asked this in a startup interview today! I tried with masters theorem but couldn’t get there.

  8. Hi,

    I’ve got a shorter code for this problem.

    public ArrayList<ArrayList> subsets(int[] S) {

    ArrayList<ArrayList> ans = new ArrayList<ArrayList>();

    ans.add(new ArrayList());

    Arrays.sort(S);

    for (int i = 0; i < S.length; i ++) {

    int curSize = ans.size();

    for (int j = 0; j < curSize; j ++) {

    ArrayList cur = new ArrayList(ans.get(j));

    cur.add(S[i]);

    ans.add(cur);

    }

    }

    return ans;

    }

Leave a Comment