簡體   English   中英

所有可能的數組子集的乘積之和

[英]Sum of product of all possible subsets of array

我編寫了一個代碼來查找所有可能的數組子集的乘積。 我得到了預期的輸出但是我無法讓它足夠快以清除時間相關的測試用例。

任何人都可以幫助我優化代碼的速度嗎?

第一個輸入(testCases)是測試用例的數量。 根據測試用例的數量,我們將具有數組(大小)和數組元素(集合)的大小。

例如,有效輸入將是:

1
3
2 3 5

哪里:

1是測試用例的數量。 3是測試集的大小, 2 3 5是輸入集的元素。

預期的產出是:

71

上述輸出的計算如下:

    {2}, {3}, {5}, {2, 3}, {3, 5}, {2, 5}, {2, 3, 5}

=>   2    3    5      6      15      10        30

=>   2 + 3 + 5 + 6 + 15 + 10 + 30

=>   71

import java.util.Scanner;

public class Test {
    static int printSubsets(int set[]) {
        int n = set.length;
        int b = 0;

        for (int i = 0; i < (1 << n); i++) {
            int a = 1;
            for (int j = 0; j < n; j++){

                if ((i & (1 << j)) > 0) {

                    a *= set[j];
                }}

            b += a;
        }
        return b;
    }

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        int testCases = scanner.nextInt();

        for (int i = 0; i < testCases; i++) {
            int size = scanner.nextInt();
            int set[] = new int[size];
            for (int j = 0; j < set.length; j++) {
                set[j] = scanner.nextInt();
            }

            int c = printSubsets(set);
            System.out.println((c - 1));

        }
        scanner.close();
    }
}

你需要使用一點數學。 假設您有3個值,就像您的示例一樣,但我們稱之為ABC

要獲得產品總和,您需要計算:

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

現在,如果我們首先計算A + B + A*B ,將其Result2 ,那么你得到:

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

我們重復一遍,所以

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

你能看到這種模式嗎? 讓我們使用4個值:

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

摘要:

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

作為代碼,這是:

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

只有一次迭代,所以O(n)

測試

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

產量

11
71
575

UPDATE

代碼也可以使用帶有Lambda表達式的Java 8 Streams,使用IntStream.of(int...)Arrays.stream(int[]) (它們執行相同的操作)來完成。

// 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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM