例如:如果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]));
答案 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]
产生:
在使用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
)是1
和0
方式。
答案 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));