【问题标题】:Java - Recursive solution for subset sumJava - 子集和的递归解决方案
【发布时间】:2021-11-23 13:58:36
【问题描述】:

我被告知要编写一个递归函数,该函数采用起始索引、整数数组和目标总和,您的目标是找出整数数组的子集加起来是否等于目标总和。

我给出的例子是 groupSum(0, {2, 4, 8}, 10) 应该返回 true,因为 2 和 8 加起来就是目标 10。到目前为止我所能做的就是基本情况。

public boolean groupSum(int start, int[] nums, int target) {
    if (nums.length == 0)
    {
        return false;
    }
    else if (start == nums.length - 1)
    {
        return nums[start] == target;
    }
    else
    {
        ?????
    }
}

我不知道我应该去哪里进行实际的递归调用。由于我无法在两次调用之间传递总和,因此在达到目标之前,我看不到如何在每个递归调用中添加一个数字。此外,如示例中所示,我不知道如何让我的代码意识到当一个数字不起作用并跳过它,就像示例中的 4 一样。我正在考虑我应该减去从 int 目标一次一个数字,然后使用新的起点和目标的新值递归调用该方法,但我不知道如何使用它来查看是否有有效的子集。

如果有任何帮助可以帮助我了解如何解决此问题,我将不胜感激,以便我完成它。谢谢!

【问题讨论】:

  • 提示:检查一组 3、2 和 1 是否可以加起来为 8。从 3 开始。你有两种情况。您需要检查剩余的集合(2和1)是否可以自己加起来8。您还需要检查剩余的集合是否可以加到8,包括3,IE剩余的集合是否可以加起来(8 - 3)。

标签: java


【解决方案1】:

正如您所指出的,您可以更改目标,而不是传递一个总和。一旦目标为零,您就知道您有一个解决方案(通过不选择剩余项目的任何成员)。

所以,在伪代码中:

hasMembersThatSumTo(list, total):
    if total == 0
        return true
    else if total < 0 or list is empty
        return false
    else
        int first = list.pop
        return hasMembersThatSumTo(list, total - first)
            or hasMembersThatSumTo(list, total)

'or'语句中的两种情况都在寻找当前元素要么在总和内要么不在总和内的情况。

【讨论】:

  • 你应该已经描述了当前元素在或不在总和中的原因和解释
【解决方案2】:

这是一个工作版本。解释见代码中的cmets。

public static boolean recursiveSumCheck(int target, int[] set) {
    //base case 1: if the set is only one element, check if element = target
    if (set.length == 1) {
        return (set[0] == target);
    }

    //base case 2: if the last item equals the target return true
    int lastItem = set[set.length - 1];
    if (lastItem == target) {
        return true;
    }

    //make a new set by removing the last item
    int[] newSet = new int[set.length - 1];
    for (int newSetIndex = 0; newSetIndex < newSet.length; newSetIndex++) {
        newSet[newSetIndex] = set[newSetIndex];
    }

    //recursive case: return true if the subset adds up to the target
    //                OR if the subset adds up to (target - removed number)
    return (recursiveSumCheck(target, newSet) || recursiveSumCheck(target - lastItem, newSet));
}

【讨论】:

    【解决方案3】:

    dynamic programming。也许这会对你有所帮助。

    【讨论】:

      【解决方案4】:

      这应该根据给定的条件工作。 初始值为start = 0

      boolean subsetSum(int start, int[] nums, int target) {
           // target is the sum you want to find in the nums array
           if (target == 0) return true;
           if (start > nums.length-1 || nums.length == 0)
              return false;
           if (nums[start] > target) 
              return subsetSum(start+1, nums, target);
           return subsetSum(start+1, nums, target) || subsetSum(start+1, nums, target - nums[start]);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-22
        • 2021-10-24
        • 2015-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多