我的程序应如下:
Input : {1,2,3,2,1,8,-3}, sum = 5
输出应为3个示例组合({2,3}, {3,2}, {8,-3})
的总和
完全等于5。
我试图用JavaScript来做,但是我很困惑。
function findSubarraySum(arr, sum) {
var res = 0;
var currentSum = 0;
for (var i = 0; i < arr.length; i++) {
currentSum += arr[i];
if (currentSum == sum)
res++;
}
return res;
}
console.log(findSubarraySum([1, 2, 3, 4], 10));
答案 0 :(得分:0)
首先,您需要一种方法来迭代所有可以选择开始和子数组边界(切片定义)的独特方法。
在下面的代码中,我使用组合函数来获取所提供数组的两个索引的所有可能组合。您可以做其他事情,例如简单的双重嵌套的for循环。
接下来,您需要根据分片定义获取数组的分片,并将元素简化为总和。 Array.prototype.reduce函数可以很好地工作。
最后,仅当减少的总和与所需总和匹配时,才希望将subArray包括在结果列表中。
// Input : {1,2,3,2,1,8,-3}, sum = 5
const { combinations, range } = (() => {
const _combinations = function*(array, count, start, result) {
if (count <= 0) {
yield [...result]; // Yes, we want to return a copy
return;
}
const nextCount = count - 1;
const end = array.length - nextCount; // leave room on the array for the next remaining elements
for (let i = start; i < end; i += 1) {
// we have already used the element at (start - 1)
result[result.length - count] = array[i];
const nextStart = i + 1; // Always choose the next element from the ones following the last chosen element
yield* _combinations(array, nextCount, nextStart, result);
}
};
function* combinations(array, count) {
yield* _combinations(array, count, 0, Array(count));
}
function* range(l) {
for (let i = 0; i < l; i += 1) {
yield i;
}
}
return {
combinations,
range,
};
})();
const subArraysBy = (predicate, array) => {
const result = [];
for (const [beg, end] of combinations([...range(array.length+1)], 2)) {
const subArray = array.slice(beg, end);
if (predicate(subArray)) {
result.push(subArray);
}
}
return result;
};
const sum = array => array.reduce((sum, e) => sum + e);
console.log(
subArraysBy(
a => sum(a) === 5,
[1, 2, 3, 2, 1, 8, -3],
),
);
参考文献:
MDN:function*-解决方案不需要
Lodash:_.range-在我的代码中实现了这一点,而不是使用lodash。它们的工作方式相似。
Python文档:combinations-我的组合实现受到python itertools的启发。