Sum of product of all possible subsets of array

前端 未结 1 1147
耶瑟儿~
耶瑟儿~ 2021-02-09 02:34

I have written a code to find Sum of product of all possible subsets of array. I\'m getting the expected output but I\'m not able to make it fast enough to clear time related te

1条回答
  •  既然无缘
    2021-02-09 03:29

    You need to use a little math. Lets say you have 3 values, like your example, but lets call them A, B, and C.

    To get sum of products, you need to calculate:

    Result3 = A + B + C + A*B + A*C + B*C + A*B*C
            = A + B + A*B + (1 + A + B + A*B) * C
    

    Now, if we calculate A + B + A*B first, calling it Result2, then you get:

    Result2 = A + B + A*B
    Result3 = Result2 + (1 + Result2) * C
    

    And we repeat that, so

    Result2 = A + (1 + A) * B
    Result1 = A
    Result2 = Result1 + (1 + Result1) * B
    

    Can you see the pattern? Let's use that with 4 values:

    Result4 = A + B + C + D + A*B + A*C + A*D + B*C + B*D + C*D
            + A*B*C + A*B*D + A*C*D + B*C*D + A*B*C*D
            =      A + B + C + A*B + A*C + B*C + A*B*C
            + (1 + A + B + C + A*B + A*C + B*C + A*B*C) * D
            = Result3 + (1 + Result3) * D
    

    Summary:

    Result1 = A
    Result2 = Result1 + (1 + Result1) * B
    Result3 = Result2 + (1 + Result2) * C
    Result4 = Result3 + (1 + Result3) * D
    

    As code, this is:

    private static long sumProduct(int... input) {
        long result = 0;
        for (int value : input)
            result += (result + 1) * value;
        return result;
    }
    

    Only one iteration, so O(n).

    Test

    System.out.println(sumProduct(2, 3));
    System.out.println(sumProduct(2, 3, 5));
    System.out.println(sumProduct(2, 3, 5, 7));
    

    Output

    11
    71
    575
    

    UPDATE

    Code can also be done using Java 8 Streams with a Lambda expression, using either IntStream.of(int...) or Arrays.stream(int[]) (they do the same).

    // Using IntStream with result as int
    private static int sumProduct(int... input) {
        return IntStream.of(input).reduce((a, b) -> a + (1 + a) * b).getAsInt();
    }
    
    // Using Arrays with result as long
    private static long sumProduct(int... input) {
        return Arrays.stream(input)
                     .asLongStream()
                     .reduce((a, b) -> a + (1 + a) * b)
                     .getAsLong();
    }
    

    0 讨论(0)
提交回复
热议问题