如何找到给定总和的数组中子数组的数量?

时间:2019-03-19 17:32:59

标签: javascript arrays

我的程序应如下:

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));

1 个答案:

答案 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:Array.prototype.reduce

  • MDN:function*-解决方案不需要

  • Lodash:_.range-在我的代码中实现了这一点,而不是使用lodash。它们的工作方式相似。

  • Python文档:combinations-我的组合实现受到python itertools的启发。