【问题标题】:Find the highest subset of an integer array whose sums add up to a given target查找整数数组的最高子集,其总和等于给定目标
【发布时间】:2016-04-12 01:21:03
【问题描述】:

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

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

例如:

如果 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

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

如果没有一对,则需要从总和小于目标的最大一对数字开始,然后循环遍历数组以查找是否存在组合。

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

请帮忙!

【问题讨论】:

  • 家庭作业问题...
  • 哦,当然,knapsack problem 的一种解决方案即将出现... ;-P
  • 你能提供一个你认为可以完成这项工作的算法的类似英语的描述吗?
  • @torazaburo 我在算法描述中添加了我认为可以在描述底部完成这项工作的算法。谢谢。
  • @deceze 其实这不是背包问题,而是子集和问题。我不是复杂性理论方面的专家,但我的感觉是,他想要找到一个涉及最大值的解决方案的条件大大简化了这个问题,它甚至可能不再是 NP 完全的。

标签: javascript loops recursion


【解决方案1】:

递归的基本模式是:

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

所以:

// 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]

【讨论】:

  • 这完全符合我的需要。非常感谢您花时间解决它并耐心地与一个完全新手程序员打交道。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 2013-11-03
  • 1970-01-01
  • 2021-01-19
  • 2021-01-08
  • 2014-04-06
  • 1970-01-01
相关资源
最近更新 更多