Obtaining a powerset of a set in Java

JavaAlgorithmSetPowerset

Java Problem Overview


The powerset of {1, 2, 3} is:

{{}, {2}, {3}, {2, 3}, {1, 2}, {1, 3}, {1, 2, 3}, {1}}

Let's say I have a Set in Java:

Set<Integer> mySet = new HashSet<Integer>();
mySet.add(1);
mySet.add(2);
mySet.add(3);
Set<Set<Integer>> powerSet = getPowerset(mySet);

How do I write the function getPowerset, with the best possible order of complexity? (I think it might be O(2^n).)

Java Solutions


Solution 1 - Java

Yes, it is O(2^n) indeed, since you need to generate, well, 2^n possible combinations. Here's a working implementation, using generics and sets:

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;
}  

And a test, given your example input:

 Set<Integer> mySet = new HashSet<Integer>();
 mySet.add(1);
 mySet.add(2);
 mySet.add(3);
 for (Set<Integer> s : SetUtils.powerSet(mySet)) {
     System.out.println(s);
 }

Solution 2 - Java

Actually, I've written code that does what you're asking for in O(1). The question is what you plan to do with the Set next. If you're just going to call size() on it, that's O(1), but if you're going to iterate it that's obviously O(2^n).

contains() would be O(n), etc.

Do you really need this?

EDIT:

This code is now available in Guava, exposed through the method Sets.powerSet(set).

Solution 3 - Java

Here's a solution where I use a generator, the advantage being, the entire power set is never stored at once... So you can iterate over it one-by-one without needing it to be stored in memory. I'd like to think it's a better option... Note the complexity is the same, O(2^n), but the memory requirements are reduced (assuming the garbage collector behaves! ;) )

/**
 *
 */
package org.mechaevil.util.Algorithms;

import java.util.BitSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author st0le
 *
 */
public class PowerSet<E> implements Iterator<Set<E>>,Iterable<Set<E>>{
    private E[] arr = null;
    private BitSet bset = null;

    @SuppressWarnings("unchecked")
    public PowerSet(Set<E> set)
    {
        arr = (E[])set.toArray();
        bset = new BitSet(arr.length + 1);
    }

    @Override
    public boolean hasNext() {
        return !bset.get(arr.length);
    }

    @Override
    public Set<E> next() {
        Set<E> returnSet = new TreeSet<E>();
        for(int i = 0; i < arr.length; i++)
        {
            if(bset.get(i))
                returnSet.add(arr[i]);
        }
        //increment bset
        for(int i = 0; i < bset.size(); i++)
        {
            if(!bset.get(i))
            {
                bset.set(i);
                break;
            }else
                bset.clear(i);
        }

        return returnSet;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Not Supported!");
    }

    @Override
    public Iterator<Set<E>> iterator() {
        return this;
    }

}

To call it, use this pattern:

        Set<Character> set = new TreeSet<Character> ();
        for(int i = 0; i < 5; i++)
            set.add((char) (i + 'A'));

        PowerSet<Character> pset = new PowerSet<Character>(set);
        for(Set<Character> s:pset)
        {
            System.out.println(s);
        }

It's from my Project Euler Library... :)

Solution 4 - Java

If n < 63, which is a reasonable assumption since you'd run out of memory (unless using an iterator implementation) trying to construct the power set anyway, this is a more concise way to do it. Binary operations are way faster than Math.pow() and arrays for masks, but somehow Java users are afraid of them...

List<T> list = new ArrayList<T>(originalSet);
int n = list.size();

Set<Set<T>> powerSet = new HashSet<Set<T>>();

for( long i = 0; i < (1 << n); i++) {
    Set<T> element = new HashSet<T>();
    for( int j = 0; j < n; j++ )
        if( (i >> j) % 2 == 1 ) element.add(list.get(j));
    powerSet.add(element); 
}

return powerSet;

Solution 5 - Java

Here is a tutorial describing exactly what you want, including the code. You're correct in that the complexity is O(2^n).

Solution 6 - Java

I came up with another solution based on @Harry He's ideas. Probably not the most elegant but here it goes as I understand it:

Let's take the classical simple example PowerSet of S P(S) = {{1},{2},{3}}. We know the formula to get the number of subsets is 2^n (7 + empty set). For this example 2^3 = 8 subsets.

In order to find each subset we need to convert 0-7 decimal to binary representation shown in the conversion table below:

ConversionTable

If we traverse the table row by row, each row will result in a subset and the values of each subset will come from the enabled bits.

Each column in the Bin Value section corresponds to the index position in the original input Set.

Here my code:

public class PowerSet {

/**
 * @param args
 */
public static void main(String[] args) {
	PowerSet ps = new PowerSet();
	Set<Integer> set = new HashSet<Integer>();
	set.add(1);
	set.add(2);
	set.add(3);
	for (Set<Integer> s : ps.powerSet(set)) {
		System.out.println(s);
	}
}

public Set<Set<Integer>> powerSet(Set<Integer> originalSet) {
	// Original set size e.g. 3
	int size = originalSet.size();
	// Number of subsets 2^n, e.g 2^3 = 8
	int numberOfSubSets = (int) Math.pow(2, size);
	Set<Set<Integer>> sets = new HashSet<Set<Integer>>();
    ArrayList<Integer> originalList = new ArrayList<Integer>(originalSet);
	for (int i = 0; i < numberOfSubSets; i++) {
		// Get binary representation of this index e.g. 010 = 2 for n = 3
		String bin = getPaddedBinString(i, size);
		//Get sub-set
		Set<Integer> set = getSet(bin, originalList));
		sets.add(set);
	}
	return sets;
}

//Gets a sub-set based on the binary representation. E.g. for 010 where n = 3 it will bring a new Set with value 2
private Set<Integer> getSet(String bin, List<Integer> origValues){
	Set<Integer> result = new HashSet<Integer>();
	for(int i = bin.length()-1; i >= 0; i--){
		//Only get sub-sets where bool flag is on
		if(bin.charAt(i) == '1'){
			int val = origValues.get(i);
			result.add(val);
		}
	}
	return result;
}

//Converts an int to Bin and adds left padding to zero's based on size
private String getPaddedBinString(int i, int size) {
	String bin = Integer.toBinaryString(i);
	bin = String.format("%0" + size + "d", Integer.parseInt(bin));
	return bin;
}

}

Solution 7 - Java

If you're using Eclipse Collections (formerly GS Collections), you can use the powerSet() method on all SetIterables.

MutableSet<Integer> set = UnifiedSet.newSetWith(1, 2, 3);
System.out.println("powerSet = " + set.powerSet());
// prints: powerSet = [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

Note: I am a committer for Eclipse Collections.

Solution 8 - Java

I was looking for a solution that wasn't as huge as the ones posted here. This targets Java 7, so it will require a handful of pastes for versions 5 and 6.

Set<Set<Object>> powerSetofNodes(Set<Object> orig) {
    Set<Set<Object>> powerSet = new HashSet<>(),
        runSet = new HashSet<>(),
        thisSet = new HashSet<>();

    while (powerSet.size() < (Math.pow(2, orig.size())-1)) {
        if (powerSet.isEmpty()) {
            for (Object o : orig) {
                Set<Object> s = new TreeSet<>();
                s.add(o);
                runSet.add(s);
                powerSet.add(s);
            }
            continue;
        }
        for (Object o : orig) {
            for (Set<Object> s : runSet) {
                Set<Object> s2 = new TreeSet<>();
                s2.addAll(s);
                s2.add(o);
                powerSet.add(s2);
                thisSet.add(s2);
            }
        }
        runSet.clear();
        runSet.addAll(thisSet);
        thisSet.clear();
    }
    powerSet.add(new TreeSet());
    return powerSet;

Here's some example code to test:

Set<Object> hs = new HashSet<>();
hs.add(1);
hs.add(2);
hs.add(3);
hs.add(4);
for(Set<Object> s : powerSetofNodes(hs)) {
    System.out.println(Arrays.toString(s.toArray()));
}

Solution 9 - Java

Here is an easy iterative O(2^n) solution:

public static Set<Set<Integer>> powerSet(List<Integer> intList){
    
    Set<Set<Integer>> result = new HashSet();
    result.add(new HashSet());
    
    for (Integer i : intList){

        Set<Set<Integer>> temp = new HashSet();
        
        for(Set<Integer> intSet : result){
            
            intSet = new HashSet(intSet);
            intSet.add(i);                
            temp.add(intSet);
        }
        result.addAll(temp);
    }
    return result;
}

Solution 10 - Java

The following solution is borrowed from my book "Coding Interviews: Questions, Analysis & Solutions":

Some integers in an array are selected that compose a combination. A set of bits is utilized, where each bit stands for an integer in the array. If the i-th character is selected for a combination, the i-th bit is 1; otherwise, it is 0. For instance, three bits are used for combinations of the array [1, 2, 3]. If the first two integers 1 and 2 are selected to compose a combination [1, 2], the corresponding bits are {1, 1, 0}. Similarly, bits corresponding to another combination [1, 3] are {1, 0, 1}. We are able to get all combinations of an array with length n if we can get all possible combinations of n bits.

A number is composed of a set of bits. All possible combinations of n bits correspond to numbers from 1 to 2^n-1. Therefore, each number in the range between 1 and 2^n-1 corresponds to a combination of an array with length n. For example, the number 6 is composed of bits {1, 1, 0}, so the first and second characters are selected in the array [1, 2, 3] to generate the combination [1, 2]. Similarly, the number 5 with bits {1, 0, 1} corresponds to the combination [1, 3].

The Java code to implement this solution looks like below:

public static ArrayList<ArrayList<Integer>> powerSet(int[] numbers) {
    ArrayList<ArrayList<Integer>> combinations = new ArrayList<ArrayList<Integer>>(); 
    BitSet bits = new BitSet(numbers.length);
    do{
        combinations.add(getCombination(numbers, bits));
    }while(increment(bits, numbers.length));
    
    return combinations;
}

private static boolean increment(BitSet bits, int length) {
    int index = length - 1;
    
    while(index >= 0 && bits.get(index)) {
        bits.clear(index);
        --index;
    }
    
    if(index < 0)
        return false;
    
    bits.set(index);
    return true;
}

private static ArrayList<Integer> getCombination(int[] numbers, BitSet bits){
    ArrayList<Integer> combination = new ArrayList<Integer>();
    for(int i = 0; i < numbers.length; ++i) {
        if(bits.get(i))
            combination.add(numbers[i]);
    }
    
    return combination;
}

The method increment increases a number represented in a set of bits. The algorithm clears 1 bits from the rightmost bit until a 0 bit is found. It then sets the rightmost 0 bit to 1. For example, in order to increase the number 5 with bits {1, 0, 1}, it clears 1 bits from the right side and sets the rightmost 0 bit to 1. The bits become {1, 1, 0} for the number 6, which is the result of increasing 5 by 1.

Solution 11 - Java

Some of the solutions above suffer when the size of the set is large because they are creating a lot of object garbage to be collected and require copying data. How can we avoid that? We can take advantage of the fact that we know how big the result set size will be (2^n), preallocate an array that big, and just append to the end of it, never copying.

The speedup grows quickly with n. I compared it to João Silva's solution above. On my machine (all measurements approximate), n=13 is 5x faster, n=14 is 7x, n=15 is 12x, n=16 is 25x, n=17 is 75x, n=18 is 140x. So that garbage creation/collection and copying is dominating in what otherwise seem to be similar big-O solutions.

Preallocating the array at the beginning appears to be a win compared to letting it grow dynamically. With n=18, dynamic growing takes about twice as long overall.

public static <T> List<List<T>> powerSet(List<T> originalSet) {
	// result size will be 2^n, where n=size(originalset)
	// good to initialize the array size to avoid dynamic growing
	int resultSize = (int) Math.pow(2, originalSet.size());
	// resultPowerSet is what we will return
	List<List<T>> resultPowerSet = new ArrayList<List<T>>(resultSize);
	
	// Initialize result with the empty set, which powersets contain by definition
	resultPowerSet.add(new ArrayList<T>(0)); 

	// for every item in the original list
	for (T itemFromOriginalSet : originalSet) {
		
		// iterate through the existing powerset result
		// loop through subset and append to the resultPowerset as we go
		// must remember size at the beginning, before we append new elements
		int startingResultSize = resultPowerSet.size();
		for (int i=0; i<startingResultSize; i++) {
			// start with an existing element of the powerset
			List<T> oldSubset = resultPowerSet.get(i);
			
			// create a new element by adding a new item from the original list
			List<T> newSubset = new ArrayList<T>(oldSubset);
			newSubset.add(itemFromOriginalSet);
			
			// add this element to the result powerset (past startingResultSize)
			resultPowerSet.add(newSubset);
		}
	}
	return resultPowerSet;
}

Solution 12 - Java

import java.util.Set;
import com.google.common.collect.*;

Set<Set<Integer>> sets = Sets.powerSet(ImmutableSet.of(1, 2, 3));

Solution 13 - Java

If S is a finite set with N elements, then the power set of S contains 2^N elements. The time to simply enumerate the elements of the powerset is 2^N, so O(2^N) is a lower bound on the time complexity of (eagerly) constructing the powerset.

Put simply, any computation that involves creating powersets is not going to scale for large values of N. No clever algorithm will help you ... apart from avoiding the need to create the powersets!

Solution 14 - Java

One way without recursion is the following: Use a binary mask and make all the possible combinations.

public HashSet<HashSet> createPowerSet(Object[] array)
{
	HashSet<HashSet> powerSet=new HashSet();
	boolean[] mask= new boolean[array.length];
	
	for(int i=0;i<Math.pow(2, array.length);i++)
	{
		HashSet set=new HashSet();
		for(int j=0;j<mask.length;j++)
		{
			if(mask[i])
				set.add(array[j]);
		}
		powerSet.add(set);		
		
		increaseMask(mask);
	}
	
	return powerSet;
}

public void increaseMask(boolean[] mask)
{
	boolean carry=false;
	
	if(mask[0])
		{
			mask[0]=false;
			carry=true;
		}
	else
		mask[0]=true;
	
	for(int i=1;i<mask.length;i++)
	{
		if(mask[i]==true && carry==true)
		mask[i]=false;
		else if (mask[i]==false && carry==true)
		{
			mask[i]=true;
			carry=false;
		}
		else 
			break;
			
	}
	
}

Solution 15 - Java

Algorithm:

Input: Set[], set_size

  1. Get the size of power set powet_set_size = pow(2, set_size) 2 Loop for counter from 0 to pow_set_size (a) Loop for i = 0 to set_size (i) If ith bit in counter is set Print ith element from set for this subset (b) Print seperator for subsets i.e., newline

#include <stdio.h>
#include <math.h>
 
void printPowerSet(char *set, int set_size)
{
    /*set_size of power set of a set with set_size
      n is (2**n -1)*/
    unsigned int pow_set_size = pow(2, set_size);
    int counter, j;
 
    /*Run from counter 000..0 to 111..1*/
    for(counter = 0; counter < pow_set_size; counter++)
    {
      for(j = 0; j < set_size; j++)
       {
          /* Check if jth bit in the counter is set
             If set then pront jth element from set */
          if(counter & (1<<j))
            printf("%c", set[j]);
       }
       printf("\n");
    }
}
 
/*Driver program to test printPowerSet*/
int main()
{
    char set[] = {'a','b','c'};
    printPowerSet(set, 3);
 
    getchar();
    return 0;
}

Solution 16 - Java

This is my recursive solution which can get the power set of any set using Java Generics. Its main idea is to combine the head of the input array with all the possible solutions of the rest of the array as follows.

import java.util.LinkedHashSet;
import java.util.Set;

public class SetUtil {
    private static<T>  Set<Set<T>> combine(T head, Set<Set<T>> set) {
        Set<Set<T>> all = new LinkedHashSet<>();
                
        for (Set<T> currentSet : set) {
            Set<T> outputSet = new LinkedHashSet<>();
            
            outputSet.add(head);
            outputSet.addAll(currentSet);
            
            all.add(outputSet);
        }
        
        all.addAll(set);        
        
        return all;
    }
    
    //Assuming that T[] is an array with no repeated elements ...
    public static<T> Set<Set<T>> powerSet(T[] input) {
        if (input.length == 0) {
            Set <Set<T>>emptySet = new LinkedHashSet<>();
    
            emptySet.add(new LinkedHashSet<T>());
    
            return emptySet;
        }

        T head = input[0];
        T[] newInputSet = (T[]) new Object[input.length - 1];

        for (int i = 1; i < input.length; ++i) {
            newInputSet[i - 1] = input[i];
        }

        Set<Set<T>> all = combine(head, powerSet(newInputSet));

        return all;
    }
    
    public static void main(String[] args) {            
        Set<Set<Integer>> set = SetUtil.powerSet(new Integer[] {1, 2, 3, 4, 5, 6});

        System.out.println(set);
    }
}

This will output:

[[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5], [1, 2, 3, 4, 6], [1, 2, 3, 4], [1, 2, 3, 5, 6], [1, 2, 3, 5], [1, 2, 3, 6], [1, 2, 3], [1, 2, 4, 5, 6], [1, 2, 4, 5], [1, 2, 4, 6], [1, 2, 4], [1, 2, 5, 6], [1, 2, 5], [1, 2, 6], [1, 2], [1, 3, 4, 5, 6], [1, 3, 4, 5], [1, 3, 4, 6], [1, 3, 4], [1, 3, 5, 6], [1, 3, 5], [1, 3, 6], [1, 3], [1, 4, 5, 6], [1, 4, 5], [1, 4, 6], [1, 4], [1, 5, 6], [1, 5], [1, 6], [1], [2, 3, 4, 5, 6], [2, 3, 4, 5], [2, 3, 4, 6], [2, 3, 4], [2, 3, 5, 6], [2, 3, 5], [2, 3, 6], [2, 3], [2, 4, 5, 6], [2, 4, 5], [2, 4, 6], [2, 4], [2, 5, 6], [2, 5], [2, 6], [2], [3, 4, 5, 6], [3, 4, 5], [3, 4, 6], [3, 4], [3, 5, 6], [3, 5], [3, 6], [3], [4, 5, 6], [4, 5], [4, 6], [4], [5, 6], [5], [6], []]

Solution 17 - Java

Another sample implementation:

 public static void main(String args[])
    {
        int[] arr = new int[]{1,2,3,4};
        // Assuming that number of sets are in integer range
        int totalSets = (int)Math.pow(2,arr.length);
        for(int i=0;i<totalSets;i++)
        {
            String binaryRep = Integer.toBinaryString(i);      
            for(int j=0;j<binaryRep.length();j++)
            {
                int index=binaryRep.length()-1-j;
                if(binaryRep.charAt(index)=='1')
                System.out.print(arr[j] +" ");       
            }
            System.out.println();
        }
    }

Solution 18 - Java

This is my approach with lambdas.

public static <T> Set<Set<T>> powerSet(T[] set) {
      return IntStream
			.range(0, (int) Math.pow(2, set.length))
            .parallel() //performance improvement
			.mapToObj(e -> IntStream.range(0, set.length).filter(i -> (e & (0b1 << i)) != 0).mapToObj(i -> set[i]).collect(Collectors.toSet()))
			.map(Function.identity())
			.collect(Collectors.toSet());
        }

Or in parallel (see parallel() comment):

Size of input set: 18

Logical processors: 8 à 3.4GHz

Performance improvement: 30%

Solution 19 - Java

// input: S
// output: P
// S = [1,2]
// P = [], [1], [2], [1,2]

public static void main(String[] args) {
	String input = args[0];
	String[] S = input.split(",");
	String[] P = getPowerSet(S);
	if (P.length == Math.pow(2, S.length)) {
		for (String s : P) {
			System.out.print("[" + s + "],");
		}
	} else {
		System.out.println("Results are incorrect");
	}
}

private static String[] getPowerSet(String[] s) {
	if (s.length == 1) {
		return new String[] { "", s[0] };
	} else {
		String[] subP1 = getPowerSet(Arrays.copyOfRange(s, 1, s.length));
		String[] subP2 = new String[subP1.length];
		for (int i = 0; i < subP1.length; i++) {
			subP2[i] = s[0] + subP1[i];
		}
		String[] P = new String[subP1.length + subP2.length];
		System.arraycopy(subP1, 0, P, 0, subP1.length);
		System.arraycopy(subP2, 0, P, subP1.length, subP2.length);
		return P;
	}

}

Solution 20 - Java

I recently had to use something like this, but needed the smallest sublists (with 1 element, then 2 elements, ...) first. I did not want to include the empty nor the whole list. Also, I did not need a list of all the sublists returned, I just needed to do some stuff with each.

Wanted to do this without recursion, and came up with the following (with the "doing stuff" abstracted into a functional interface):

@FunctionalInterface interface ListHandler<T> {
    void handle(List<T> list);
}


public static <T> void forAllSubLists(final List<T> list, ListHandler handler) {
    int     ll = list.size();   // Length of original list
    int     ci[] = new int[ll]; // Array for list indices
    List<T> sub = new ArrayList<>(ll);  // The sublist
    List<T> uml = Collections.unmodifiableList(sub);    // For passing to handler
    
    for (int gl = 1, gm; gl <= ll; gl++) {  // Subgroup length 1 .. n-1
        gm = 0; ci[0] = -1; sub.add(null);  // Some inits, and ensure sublist is at least gl items long

        do {
                ci[gm]++;                       // Get the next item for this member
                    
                if (ci[gm] > ll - gl + gm) {    // Exhausted all possibilities for this position
                        gm--; continue;         // Continue with the next value for the previous member
                }
                
                sub.set(gm, list.get(ci[gm]));  // Set the corresponding member in the sublist

                if (gm == gl - 1) {             // Ok, a sublist with length gl
                        handler.handle(uml);    // Handle it
                } else {
                        ci[gm + 1] = ci[gm];    // Starting value for next member is this 
                        gm++;                   // Continue with the next member
                }
        } while (gm >= 0);  // Finished cycling through all possibilities
    }   // Next subgroup length
}

In this way, it's also easy to limit it to sublists of specific lengths.

Solution 21 - Java

public class PowerSet {
    public static List<HashSet<Integer>> powerset(int[] a) {
        LinkedList<HashSet<Integer>> sets = new LinkedList<HashSet<Integer>>();
        int n = a.length;
        for (int i = 0; i < 1 << n; i++) {
            HashSet<Integer> set = new HashSet<Integer>();
            for (int j = 0; j < n; j++) {
                if ((1 << j & i) > 0)
                    set.add(a[j]);
            }
            sets.add(set);
        }
        return sets;
    }

    public static void main(String[] args) {
        List<HashSet<Integer>> sets = PowerSet.powerset(new int[]{ 1, 2, 3 });
        for (HashSet<Integer> set : sets) {
            for (int i : set)
                System.out.print(i);
            System.out.println();
        } 
    }
}

Solution 22 - Java

Yet another solution - with java8+ streaming api It is lazy and ordered so it returns correct subsets when it is used with "limit()".

 public long bitRangeMin(int size, int bitCount){
    BitSet bs = new BitSet(size);
    bs.set(0, bitCount);
    return bs.toLongArray()[0];
}

public long bitRangeMax(int size, int bitCount){
    BitSet bs = BitSet.valueOf(new long[]{0});
    bs.set(size - bitCount, size);
    return bs.toLongArray()[0];
}

public <T> Stream<List<T>> powerSet(Collection<T> data)
{
    List<T> list = new LinkedHashSet<>(data).stream().collect(Collectors.toList());
    Stream<BitSet> head = LongStream.of(0).mapToObj( i -> BitSet.valueOf(new long[]{i}));
    Stream<BitSet> tail = IntStream.rangeClosed(1, list.size())
            .boxed()
            .flatMap( v1 -> LongStream.rangeClosed( bitRangeMin(list.size(), v1), bitRangeMax(list.size(), v1))
                    .mapToObj(v2 -> BitSet.valueOf(new long[]{v2}))
                    .filter( bs -> bs.cardinality() == v1));

    return Stream.concat(head, tail)
            .map( bs -> bs
                    .stream()
                    .mapToObj(list::get)
                    .collect(Collectors.toList()));
}

And the client code is

@Test
public void testPowerSetOfGivenCollection(){
    List<Character> data = new LinkedList<>();
    for(char i = 'a'; i < 'a'+5; i++ ){
        data.add(i);
    }
    powerSet(data)
            .limit(9)
            .forEach(System.out::print);

}

/* Prints : [][a][b][c][d][e][a, b][a, c][b, c] */

Solution 23 - Java

We could write the power set with or without using recursion. Here is an attempt without recursion:

public List<List<Integer>> getPowerSet(List<Integer> set) {
	List<List<Integer>> powerSet = new ArrayList<List<Integer>>();
	int max = 1 << set.size();
	for(int i=0; i < max; i++) {
		List<Integer> subSet = getSubSet(i, set);
		powerSet.add(subSet);
	}
	return powerSet;
}

private List<Integer> getSubSet(int p, List<Integer> set) {
	List<Integer> subSet = new ArrayList<Integer>();
	int position = 0;
	for(int i=p; i > 0; i >>= 1) {
		if((i & 1) == 1) {
			subSet.add(set.get(position));
		}
		position++;
	}
	return subSet;
}

Solution 24 - Java

A sub-set of t is any set that can be made by removing zero or more elements of t. The withoutFirst subset adds the subsets of t that are missing the first element and the for loop will deal with adding subsets with the first element. For example, if t contained the elements ["1", "2", "3"], missingFirst will add [[""], ["2"], ["3"], ["2","3"]] and the for loop will stick the "1" in front of these element and add it to the newSet. So we'll end up with [[""], ["1"], ["2"], ["3"], ["1", "2"], ["1", "3"], ["2","3"], ["1", "2", "3"]].

public static Set<Set<String>> allSubsets(Set<String> t) {
		Set<Set<String>> powerSet = new TreeSet<>();
		if(t.isEmpty()) {
			powerSet.add(new TreeSet<>());
			return powerSet;
		}
		String first = t.get(0);
		Set<Set<String>> withoutFirst = allSubsets(t.subSet(1, t.size()));
		for (List<String> 1st : withoutFirst) {
			Set<String> newSet = new TreeSet<>();
			newSet.add(first);
			newSet.addAll(lst);
			powerSet.add(newSet);
		}
		powerSet.addAll(withoutFirst);
		return powerSet;
	}

Solution 25 - Java

Here is to generate a power set. The idea is first = S[0] and smaller sets be S[1,...n].

Compute all subsets of smallerSet and put them in allsubsets.

For each subsets in allsubsets, clone it and add first to the subset.

ArrayList<ArrayList<Integer>> getSubsets(ArrayList<Integer> set, int index){
	ArrayList<ArrayList<Integer>> allsubsets;
	if(set.size() == index){
		allsubsets = new ArrayList<ArrayList<Integer>>();
		allsubsets.add(new ArrayList<Integer>()); // the empty set 
	}else{
		allsubsets = getSubsets(set, index+1);
		int item = set.get(index);

		ArrayList<ArrayList<Integer>> moresubsets = new ArrayList<ArrayList<Integer>>();

		for(ArrayList<Integer> subset: allsubsets){
			ArrayList<Integer> newsubset = new ArrayList<Integer>();

			newsubset.addAll(subset);
			newsubset.add(item);
			moresubsets.add(newsubset);

		}

		moresubsets.addAll(moresubsets);

	}

	return allsubsets;
}

Solution 26 - Java

package problems;

import java.util.ArrayList;
import java.util.List;

public class SubsetFinderRecursive {
	public static void main(String[] args) {
		//input
		int[] input = new int[3];
		for(int i=0; i<input.length; i++) {
			input[i] = i+1;
		}
		// root node of the tree
		Node root = new Node();
		
		// insert values into tree
		for(int i=0; i<input.length; i++) {
			insertIntoTree(root, input[i]);
		}
		
		// print leaf nodes for subsets
		printLeafNodes(root);
	}
	
	static void printLeafNodes(Node root) {
		
		if(root == null) {
			return;
		}
		
		// Its a leaf node
		if(root.left == null && root.right == null) {
			System.out.println(root.values);
			return;
		}
		
		// if we are not at a leaf node, then explore left and right
		
		if(root.left !=null) {
			printLeafNodes(root.left);
		}
		
		if(root.right != null) {
			printLeafNodes(root.right);
		}
	}
	
	static void insertIntoTree(Node root, int value) {
		
		// Error handling
		if(root == null) {
			return;
		}
		
		// if there is a sub tree then go down
		if(root.left !=null && root.right != null) {
			insertIntoTree(root.left, value);
			insertIntoTree(root.right, value);
		}
		
		// if we are at the leaf node, then we have 2 choices
		// Either exclude or include
		if(root.left == null && root.right == null) {
			// exclude
			root.left = new Node();
			root.left.values.addAll(root.values);
			// include
			root.right = new Node();
			root.right.values.addAll(root.values);
			root.right.values.add(value);
			return;
		}
	}

}

class Node {
	Node left;
	Node right;
	List<Integer> values = new ArrayList<Integer>();
}

Solution 27 - Java

This function solved this problem by recursion but make variable named powerset as a Global Variable:

static ArrayList<ArrayList<Integer>> powerSet = new ArrayList<>();

public static void getPowerSet(Queue<Integer> a) {
    int n = a.poll();
    if (!a.isEmpty()) {
        getPowerSet(a);
    }
    int s = powerSet.size();
    for (int i = 0; i < s; i++) {
        ArrayList<Integer> ne = new ArrayList<>();
        for (int j = 0; j < powerSet.get(i).size(); j++) {
            ne.add(powerSet.get(i).get(j));
        }
        ne.add(n);
        powerSet.add(ne);
    }
    ArrayList<Integer> p = new ArrayList<>();
    p.add(n);
    powerSet.add(p);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionManuel AraozView Question on Stackoverflow
Solution 1 - JavaJoão SilvaView Answer on Stackoverflow
Solution 2 - JavaKevin BourrillionView Answer on Stackoverflow
Solution 3 - Javast0leView Answer on Stackoverflow
Solution 4 - JavaAndrew MaoView Answer on Stackoverflow
Solution 5 - JavaAdamskiView Answer on Stackoverflow
Solution 6 - JavaAdolfo PerezView Answer on Stackoverflow
Solution 7 - JavaCraig P. MotlinView Answer on Stackoverflow
Solution 8 - JavaBenView Answer on Stackoverflow
Solution 9 - Javajump3rView Answer on Stackoverflow
Solution 10 - JavaHarry HeView Answer on Stackoverflow
Solution 11 - JavaGeorge FairbanksView Answer on Stackoverflow
Solution 12 - JavaBaxView Answer on Stackoverflow
Solution 13 - JavaStephen CView Answer on Stackoverflow
Solution 14 - JavaOrestisView Answer on Stackoverflow
Solution 15 - JavagauravView Answer on Stackoverflow
Solution 16 - JavaHazem SalehView Answer on Stackoverflow
Solution 17 - JavaSandeepView Answer on Stackoverflow
Solution 18 - JavaWernerView Answer on Stackoverflow
Solution 19 - JavaNeyyadupakkam SundarasekaranView Answer on Stackoverflow
Solution 20 - JavatijmenView Answer on Stackoverflow
Solution 21 - JavaSelim EkizogluView Answer on Stackoverflow
Solution 22 - JavaekobirView Answer on Stackoverflow
Solution 23 - JavaYuviView Answer on Stackoverflow
Solution 24 - JavaMr. HView Answer on Stackoverflow
Solution 25 - Javauser3773246View Answer on Stackoverflow
Solution 26 - JavaPrakash DevtaView Answer on Stackoverflow
Solution 27 - Javaإسلام أحمدView Answer on Stackoverflow