Obtaining a powerset of a set in Java

后端 未结 26 1740
青春惊慌失措
青春惊慌失措 2020-11-22 11:33

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:<

26条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-22 11:56

    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> powerSet(int[] numbers) {
        ArrayList> combinations = new ArrayList>(); 
        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 getCombination(int[] numbers, BitSet bits){
        ArrayList combination = new ArrayList();
        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.

提交回复
热议问题