找到整数数组的最高子集,其总和加起来为给定目标

时间:2016-01-07 15:18:41

标签: javascript loops recursion

我试图在数组中找到一个值的子集,它们加起来给定的数字并返回该子集的数组。我需要返回数组包含最高可能的最大值。

整数数组将始终按升序排列,但不会始终存在有效答案。如果没有有效的答案,我需要按照“无效答案”的字样返回一个字符串。

例如:

如果int数组是:[1, 2, 3, 5, 7, 9, 11]且目标是19 - 我希望返回数组为[1, 7, 11]。 我不想返回[9, 7, 3],因为11大于9,我不想返回[3, 5, 11],因为7大于5 }}

我假设我需要在递归函数中使用for循环来获得我的答案但是却无法弄清楚如何去做。

我在Java中发现了问题的变体: https://codereview.stackexchange.com/questions/36214/find-all-subsets-of-an-int-array-whose-sums-equal-a-given-target

我还在JavaScript中找到了一个返回值对的解决方案(虽然这很简单): https://codereview.stackexchange.com/questions/74152/given-an-array-of-integers-return-all-pairs-that-add-up-to-100

我在想你需要用数组的最后一个元素开始你的循环,然后在数组中向后循环,检查是否有2个数字的组合,其总和是目标。

如果没有一对,则需要从总数小于目标的最高数字对开始,并通过数组循环以查找是否存在组合。

此操作需要继续,直到找到子集或您发现没有有效答案。

请帮忙!

1 个答案:

答案 0 :(得分:2)

递归的基本模式是:

  1. 返回简单案例的已知值。对于这个问题,简单的情况是(a)目标为0(解决方案是空数组)和(b)负目标(失败)。
  2. 根据答案递归并返回一些计算。对于这个问题,我们查看每个候选值,并使用减去该值的目标递归,返回由递归结果和添加当前元素组成的数组。
  3. 所以:

    // Find subset of a that sums to n.
    function subset_sum(n, a) {
      // SIMPLE CASES
      if (n < 0)   return null;       // Nothing adds up to a negative number
      if (n === 0) return [];         // Empty list is the solution for a target of 0
    
      // RECURSIVE CASE
      a = a.slice();
      while (a.length) {              // Try remaining values
        var v = a.shift();            // Take next value
        var s = subset_sum(n - v, a); // Find solution recursively
        if (s) return s.concat(v);    // If solution, return
      }
    }
    

    要强制首先要使用更高值的规则,请将此函数传递给按预先排序的值数组。

    > subset_sum(19, [11, 9, 7, 5, 3, 2, 1])
    < [1, 7, 11]