【问题标题】:Finding all possible subset sum which is equal to 0 out of set of positive and negative numbers? [duplicate]从一组正数和负数中找出所有可能等于 0 的子集总和? [复制]
【发布时间】:2016-07-28 11:53:03
【问题描述】:

您有一个包含一组正数和负数的数组,打印所有等于 0 的子集总和。

我可以想到一种方法,我可以制作 givcen 数组的所有 powerset 并检查它们的总和是否为 0。但是这不像优化的解决方案 我。

在网上阅读后看起来有点类似的问题,看起来可以通过如下程序的动态规划来解决,以查找是否存在组合 以 sum 11 为例?

public boolean subsetSum(int input[], int total) {

        boolean T[][] = new boolean[input.length + 1][total + 1];
        for (int i = 0; i <= input.length; i++) {
            T[i][0] = true;
        }

        for (int i = 1; i <= input.length; i++) {
            for (int j = 1; j <= total; j++) {
                if (j - input[i - 1] >= 0) {
                    T[i][j] = T[i - 1][j] || T[i - 1][j - input[i - 1]];
                } else {
                    T[i][j] = T[i-1][j];
                }
            }
        }
        return T[input.length][total];

    }




public static void main(String args[]) {
    TestDynamic ss = new TestDynamic();
   int arr1[] = {2, 3, 7, 8};
    System.out.print(ss.subsetSum(arr1, 11));

}

但我不确定如何将上述程序扩展到

1) 包含负数
2)找到元素的组合使总和为零(上面的程序只是发现它是否可能使给定的总和但没有 找出哪一组数字使它为零)

【问题讨论】:

标签: java algorithm dynamic-programming


【解决方案1】:

这是一个完整的 Javascript 实现。您可以使用 node.js 运行它。

function target_sum(a, k, x)
{
    if (k == a.length) return [];
    if (a[k] == x) {
        return [[a[k]]];
    } else {
        var s = target_sum(a, k + 1, x);        // not using a[k]
        var t = target_sum(a, k + 1, x - a[k]); // using a[k]
        for (var i = 0; i < t.length; ++i) {
            t[i].unshift(a[k]); // a[k] is part of the solution
            s.push(t[i]);       // merge t[] into s[]
        }
        return s;
    }
}

var s = target_sum([1,4,5,2,7,8,-3,-5,-6,9,3,-7,-1,5,6], 0, 0);
for (var i = 0; i < s.length; ++i)
    console.log(s[i].join(","));

请注意,这是一个指数算法。不要在大型​​数组上使用它。

Erwin Rooijakkers 也指出了正确的方向。特别是,this post 给出了另一种算法。我对以下内容可能是错误的——我相信算法会以速度换取空间。它避免了将数组暂存到调用堆栈中,但它必须进行更多的递归才能实现这一点。

编辑:关于你提到的算法。它不是指数的,但如果我是对的,它只适用于正数。它的时间复杂度也与目标总和成正比,根据输入可能并不理想。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多