我正按照以下指南编写函数:
给定一系列整数,是否可以从起始索引开始选择一组整数,以便该组与给定目标相加?但是,附加约束必须选择所有6个。 (不需要循环。)
groupSum6(0, {5, 6, 2}, 8) → true
groupSum6(0, {5, 6, 2}, 9) → false
groupSum6(0, {5, 6, 2}, 7) → false
这是解决方案:
public boolean groupSum6(int start, int[] nums, int target) {
if (start == nums.length) {
if (target == 0) {
return true;
}
return false;
}
if (nums[start] == 6) {
return groupSum6(start + 1, nums, target - nums[start]);
}
if (groupSum6(start + 1, nums, target - nums[start])) {
return true;
}
return groupSum6(start + 1, nums, target);
}
我对这为何如此有用感到困惑。我理解它是如何增加6s的,但是其他数字在哪里被测试以确定它们是否会在添加6s之后加起来?其他非6号码在哪里添加?
答案 0 :(得分:2)
这样做的原因是递归调用总是检查当前索引处的数字是否为6并从目标中减去该数字。所以评估的顺序是:
1)
if (start == nums.length) {
if (target == 0) {
return true;
}
return false;
}
检查传递的索引是否是数组的长度(这意味着索引是BEYOND数组的边界 - 数组的最后一个索引将是nums [nums.length - 1])。如果是,则AND如果目标为0,则返回true。否则返回false,因为没有更多值要检查
2) if(nums [start] == 6){ return groupSum6(start + 1,nums,target - nums [start]); }
检查索引处的数字是否为6.如果是,则从目标中减去6,将1添加到索引,并检查其余值。
3)否则......
if (groupSum6(start + 1, nums, target - nums[start])) {
return true;
}
评估数组的其余部分是否可以添加到目标。如果它确实返回true。关键是要注意,在我们检查值是否为6之后,此步骤将始终发生。实际上,您正在寻找一个解决方案,用于计算起始索引中的数字。如果找到解决方案,我们可以结束。如果使用num [start]处的数字找不到解,那么我们继续:
4)
return groupSum6(start + 1, nums, target);
检查当我们不在num [start]处使用数字时存在的解决方案。
关键是每次进行递归调用时,首先检查6(假设你没有超出数组的范围)。
答案 1 :(得分:1)
这个想法是测试所有可能的子阵列选项,例如"如果我得到下一个元素会发生什么?"并且..."如果我不这样做会发生什么?"。
因此,对于数组中的任何元素,您正在进行两次递归调用(两个选项,无论是否接受),如果其中一个正常,则达到解决方案(因此返回true)。
在下一个递归调用中,您选择数字,因此您使用下一个索引元素(start + 1)调用并从目标中减去拾取的数字(假设您的目标是8,当前元素是2 ...递归调用是检查目标8-2 = 6的下一个数字。
if (groupSum6(start + 1, nums, target - nums[start])) {
return true;
}
下一个递归通话是相同的,但你不会选择当前的号码,所以...目标将是相同的(在前面的例子中,你将检查目标8的下一个号码);
return groupSum6(start + 1, nums, target);
而且......这里有6个限制......如果你找到了6个,那么你没有其他选择而不是选择这个数字......所以你把这个条件放在第一位(在这种情况下只有一个打电话,因为你没有选择):
if (nums[start] == 6) {
return groupSum6(start + 1, nums, target - nums[start]);
}
答案 2 :(得分:0)
只需检查数字是否为6,然后决定跳过它
public boolean groupSum6(int start, int[] nums, int target) {
//exit condition and if target becomes 0
if(start >= nums.length) return (target ==0);
// subtracting the number at start from target and make a recursive //call to groupSum6
if(groupSum6(start+1 , nums , target - nums[start])) return true;
//check if the number at start is 6 or not then decide to skip it
if(nums[start] != 6 && groupSum6(start+1 , nums , target)) return true;
//if target does not becomes 0
return false;
}