我需要弄清楚如何递归确定是否存在元素选择,以使选定元素的总和与给定整数列表的未选定元素的总和相同。
例如,集合
nums = [1,3,5,3]
返回 true ,因为子集可以是[3,3]和[1,5],这两个列表的总和为6,因此该方法应返回 true 。如果该子集不存在,则应返回 false 。
我有代码:
private static boolean canFind(int[] nums, int index, int sumOne, int sumTwo) {
if (index == nums.length) {
return false;
}
if (oneSum == twoSum) {
return true;
}
if (oneSum < twoSum) {
return canFind(nums, index + 1, sumOne + nums[index], sumTwo);
}
return canFind(nums, index + 1, sumOne, sumTwo + nums[index]);
}
但是我不知道为什么这不起作用,甚至为什么不起作用。
答案 0 :(得分:1)
递归canFind()
方法的思想是:
index
,并且
到目前为止,已经收集了两个总和sumOne
和sumTwo
,是否有可能
找到剩余数字的解决方案?在详细查看代码之前,让我们进一步澄清一下任务(如果我理解正确的话):为了找到有效的解决方案,必须对每个数字进行计数,无论是sumOne
还是{{1 }}。不允许跳过数字或同时计算两个数字。
因此,在解决方案过程中的任何时候,您都可以选择是在sumTwo
还是sumOne
中添加当前数字,这就是您在两个递归调用中正确执行的操作< / p>
sumTwo
和
canFind(nums, index + 1, sumOne + nums[index], sumTwo)
但是通话周围有问题。您不知道将当前数字添加到 canFind(nums, index + 1, sumOne, sumTwo + nums[index])
或sumOne
对于解决方案是否正确,因此您应该尝试两种方式,如果其中一种成功,则返回true。如果较小,您的代码将添加到sumTwo
,否则添加到sumOne
。尽管这似乎是合理的,但这并不一定导致解决方案。因此,您应该将该部分更改为
sumTwo
我们必须继续尝试多长时间?直到我们到达数组末尾为止,因为我们不允许遗漏任何数字。
当我们到达数组末尾时,是否有解决方案?如果两个和相等,这是一个解决方案。
因此,在尝试递归调用之前,我们应该检查数组的结尾:
if (canFind(nums, index + 1, sumOne + nums[index], sumTwo)) {
// if there's some solution by adding to sumOne, we're finished.
return true;
} else if (canFind(nums, index + 1, sumOne, sumTwo + nums[index])) {
// if there's some solution by adding to sumTwo, we're finished.
return true;
} else {
// if both tries didn't succeed, thre's no solution
// starting from the given situation
return false;
}
将它们放在一起:
if (index == nums.length) {
if (sumOne == sumTwo) {
return true;
} else {
return false;
}
}
这基本上应该可以完成工作。