递归混乱

时间:2014-10-18 19:23:40

标签: java string recursion

我正按照以下指南编写函数:

给定一系列整数,是否可以从起始索引开始选择一组整数,以便该组与给定目标相加?但是,附加约束必须选择所有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号码在哪里添加?

3 个答案:

答案 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;  
}