我很确定我彻底理解了只有一次递归的方法是如何工作的。
例如:计算阶乘。
对于这些方法,我甚至可以想象出堆栈中发生的情况以及每个堆栈级别返回的值。
但是,每当我遇到具有双重递归的方法时,噩梦就开始了。
下面是来自Coding Bat的一个具有双重递归的递归问题:
例如,给定一个int数组,是否可以选择其中一组int,使其总和等于给定目标?如果是,则为true。如果不是,则为false。您使用3个参数:起始索引start,一个int数组nums,目标int值target。
以下是此问题的解决方案。
我的理解是这样的:假如我有一个数组{2,4,8},起始索引为0,目标值为10。那么(0,{2,4,8},10)会作为参数传入方法中,函数将在此重新调用。
所以它变成了
有人能为我解释一下吗?当人们使用双重递归时,他们能够真正可视化会发生什么吗?还是他们只是希望基本情况和递归能够正常工作?我认为这适用于所有编写归并排序、汉诺塔算法等的人们。
非常感谢任何帮助。
public int factorial(int n){ //factorial recursion
if(n==0){
return 1;
}
else{
return n*factorial(n-1);
}
}
对于这些方法,我甚至可以想象出堆栈中发生的情况以及每个堆栈级别返回的值。
但是,每当我遇到具有双重递归的方法时,噩梦就开始了。
下面是来自Coding Bat的一个具有双重递归的递归问题:
例如,给定一个int数组,是否可以选择其中一组int,使其总和等于给定目标?如果是,则为true。如果不是,则为false。您使用3个参数:起始索引start,一个int数组nums,目标int值target。
以下是此问题的解决方案。
public boolean groupSum(int start, int[] nums, int target) {
if (start >= nums.length) return (target == 0);
if (groupSum(start + 1, nums, target - nums[start])) return true;
if (groupSum(start + 1, nums, target)) return true;
return false;
}
我的理解是这样的:假如我有一个数组{2,4,8},起始索引为0,目标值为10。那么(0,{2,4,8},10)会作为参数传入方法中,函数将在此重新调用。
if (groupSum(start + 1, nums, target - nums[start])) return true;
所以它变成了
(1,{2,4,8},8)
,并且一遍又一遍地重复,直到开始索引达到3。当它达到3时,最后一层的堆栈进入第二次递归调用。这是我开始迷失发生了什么的地方。有人能为我解释一下吗?当人们使用双重递归时,他们能够真正可视化会发生什么吗?还是他们只是希望基本情况和递归能够正常工作?我认为这适用于所有编写归并排序、汉诺塔算法等的人们。
非常感谢任何帮助。
groupSum()
内部对groupSum()
的第二次调用并没有使堆栈变得两倍深。 - NickJ