1

To the get the power set of a list, I implemented the following:

public static ArrayList<ArrayList<Integer>> getAllSubsets(ArrayList<Integer> set, int index, ArrayList<Integer> subset){
    ArrayList<ArrayList<Integer>> subsets = new ArrayList<ArrayList<Integer>>();

    if(index == set.size()){
        subsets.add(new ArrayList<Integer>(subset));
        return subsets;
    }

    subsets.addAll(getAllSubsets(set, index + 1, subset));
    subset.add(set.get(index));
    subsets.addAll(getAllSubsets(set, index + 1, subset));
    subset.remove(subset.size()-1);
    return subsets;
}

Is this the optimal way to get the power set of a list using recursion? I've see tons of different ways on how to implement this on the internet but they seem do more copying (use of new) than mine.

For instance, this StackOverlow post came up on my Google searches but his implementation (Joao Silva) uses a lot of copying and seems non-optimal. However, I've seen his implementation quite often which puzzles me. Is that implementation better than the one I'm using (other that the fact he is using generics of course) ?

His code:

public static <T> Set<Set<T>> powerSet(Set<T> originalSet) {
    Set<Set<T>> sets = new HashSet<Set<T>>();
    if (originalSet.isEmpty()) {
        sets.add(new HashSet<T>());
        return sets;
    }
    List<T> list = new ArrayList<T>(originalSet);
    T head = list.get(0);
    Set<T> rest = new HashSet<T>(list.subList(1, list.size())); 
    for (Set<T> set : powerSet(rest)) {
        Set<T> newSet = new HashSet<T>();
        newSet.add(head);
        newSet.addAll(set);
        sets.add(newSet);
        sets.add(set);
    }       
    return sets;
}
Community
  • 1
  • 1

1 Answers1

2

You may find this page useful. It contains implementation of the powerset in various languages and using different methods. For Java there are three methods:

  1. Iterative
  2. Recursive
  3. and using Binary String

Actually I like the third way the most, because there is nice idea in there. The difference is, that they assume that input is a String.

BTW. if it is going to be any code that will be used in production, I'd rather avoid using recursion because of the possible problems with stack (unfortunately, there is still no support for tail recursion in Java)

Jiri Kremser
  • 12,471
  • 7
  • 45
  • 72