Javascript函数确定数字中数字的任何组合是否合计为最大值

时间:2015-09-27 13:34:16

标签: javascript arrays algorithm

例如:如果arr包含[4,6,23,10,1,3],则输出应返回true,因为4 + 6 + 10 + 3 = 23.数组不会为空,不包含所有相同的元素,可能包含负数。
我的尝试
使用递归方法查找arr的所有排列并添加元素以查看它们是否相加到数组max。该函数正确检查所有排列,但不返回正确的布尔值。

function arrayAddition(arr) {
    var arrMax = arr.sort(function(a, b) {
                     return a - b;
                 }).pop();

    function recArrAdd(sub, arr) {

        if (arr.length > 0) {
            var arrSum = sub.concat(arr[0]).reduce(function(prev, curr) {
                return prev + curr;
            });

            if (arrSum === arrMax) return true;
            recArrAdd(sub.concat(arr[0]), arr.slice(1));
            recArrAdd(sub, arr.slice(1));
        }
        return false;
    }

    return recArrAdd([], arr);
}

console.log(arrayAddition([1, 2, 3]));

3 个答案:

答案 0 :(得分:1)

我认为问题在于if (arrSum === arrMax) return true;检查。在程序执行的某些时刻arrSum实际上等于相应的arr[0]。但是当arr[0]碰巧是数组中的 MAX 元素时,就会出现误报。

因此,您必须加入另一项检查:if (arr[0] != arrMax)

此外,当if (arr.length > 0)检查失败时,您的函数不应返回 false 。相反,您可以使用全局标志变量(found,如下面的代码所示)并将其作为最终结果返回。

编辑:此外,由于性能原因,支票if (found) return true;位于recArrAdd()的顶部:它有助于避免不必要的进一步调用,因为{{1}时} found工作完成了。

例如,没有它,true被称为 255 次,被称为 187 (输入recArrAdd())。

以下是修改后的代码和一些示例输出:

[1,3,5,4,25,8,14]

产生:

enter image description here

在使用Firebug的Firefox中

答案 1 :(得分:0)

如果您的数字受到31的限制,则存在一个漂亮的解决方案:

n为最大值,arr为其余数字。然后,以下代码检查您想要的内容

var mask = 1;
for (var idx = 0; idx < arr.size; idx++) {
    mask = mask | mask << arr[idx];
}
return (mask >>> n) & 1;

使用boolean数组代替位掩码可以推广更大的限制。

一些解释。在开始时,掩码是00000001,标记为空集的总和,我们可以使0(因为1在位置0)。然后在每个步骤mask都是我们可以制作的所有总和的掩码。然后,为每个总和arr[idx]添加s,我们就可以s + arr[idx]。所以新总和的掩码为mask << arr[idx]。但我们仍然可以制作掩码mask的所有旧款。因此,掩码的新值为mask | mask << arr[idx]。最后,mask是所有可能总和的掩码,如果n可能是总和,那么第n位((mask >>> n) & 1)是10方式。

答案 2 :(得分:0)

你在寻找这样的东西吗?:

function sumEqualsMax(values) {
    var maxValue = Math.max.apply(Math, values);
    var sumParts = values.slice();
    sumParts.splice(sumParts.indexOf(maxValue), 1);

    var sumValue = sumParts.reduce(function (previousValue, currentValue) {
        return previousValue + currentValue;
    }, 0);

    return sumValue === maxValue;
}

var values = [4, 6, 23, 10, 3];
console.log(sumEqualsMax(values));