我遇到了提高编码技能的递归练习,发现了以下问题。
给定一系列整数,是否可以选择一组整数,以便该组与给定目标相加?我们的约定不是查看整个数组,而是考虑从索引开始并继续到数组末尾的数组部分。调用者可以简单地通过将start作为0来指定整个数组。不需要循环 - 递归调用沿着数组向下进行。
groupSum(0, [2, 4, 8], 10) → true
groupSum(0, [2, 4, 8], 14) → true
groupSum(0, [2, 4, 8], 9) → false
经过2天的工作和学习,我什么都没有。我检查了给定的解决方案,我仍然无法理解解决方案后一步一步调试。
public boolean groupSum(int start, int[] nums, int target) {
// Base case: if there are no numbers left, then there is a
// solution only if target is 0.
if (start >= nums.length) return (target == 0);
// Key idea: nums[start] is chosen or it is not.
// Deal with nums[start], letting recursion
// deal with all the rest of the array.
// Recursive call trying the case that nums[start] is chosen --
// subtract it from target in the call.
if (groupSum(start + 1, nums, target - nums[start])) return true;
// Recursive call trying the case that nums[start] is not chosen.
if (groupSum(start + 1, nums, target)) return true;
// If neither of the above worked, it's not possible.
return false;
}
解决方案很短,其逻辑基于组合。你怎么看待这件事?它背后的算法有什么解释?
此致
答案 0 :(得分:4)
这只是基本的回溯:
if (start >= nums.length) return (target == 0);
- 这里我们已经过了所有输入,并且当剩余的目标填充为0时,我们成功了。
if (groupSum(start + 1, nums, target - nums[start])) return true;
- 在这里,我们尝试使用start
位置的元素填充目标:
if (groupSum(start + 1, nums, target)) return true;
- 在这里,我们尝试使用位于start
从最后一个元素中读取:
答案 1 :(得分:3)
所以,让我们说你的问题是:
如果至少满足以下一个问题,则该问题属实:
因此,您将有关4元素列表的初始问题替换为关于3元素列表的两个新问题。
当你再三次这样做时,最终会得到16个关于0元素列表的问题。如果至少其中一个目标是零,那么你最初的问题的答案是肯定的。
答案 2 :(得分:0)
它基于dynamic programming。基本上你将一个问题分解为许多更容易解决的子问题。
以下是对此特定问题的一些解释:click.