【发布时间】:2016-06-16 18:28:40
【问题描述】:
我很确定我完全理解只有一次递归的方法是如何工作的。
Ex) 计算阶乘
public int factorial(int n){ //factorial recursion
if(n==0){
return 1;
}
else{
return n*factorial(n-1);
}
}
对于这些方法,我什至可以想象堆栈中发生了什么,以及在每个堆栈级别返回什么值。
但每当我遇到带有双递归的方法时,噩梦就开始了。
下面是来自编码bat的双重递归的递归问题。
Ex) 给定一个整数数组,是否可以选择一组整数,使得该组总和为给定的目标?如果是,是的。如果不是,则为假。 您使用 3 个参数;起始索引 start,一个 int Array 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. 最后一层(?)的堆栈进入第二个递归调用。这就是我开始忘记正在发生的事情的地方。
谁能帮我分析一下?当人们使用双重递归时,(我知道它非常低效,在实践中,几乎没有人因为它的低效而使用它。但只是为了理解它。)他们真的能想象会发生什么吗?还是他们只是使用它希望基本案例和递归能够正常工作?我认为这通常适用于所有编写合并排序、河内塔算法等的人。
非常感谢任何帮助..
【问题讨论】:
-
你在这里发明了术语。这不是“双重递归”——你所展示的是一个普通的递归。另外,就像一位智者曾经说过的那样,
to understand recursion, you have to first understand recursion。 -
好吧,我想我还没有理解递归。所以请赐教。
-
这不是“双重”递归,因为在
groupSum()内对groupSum()的第二次调用不会使堆栈深度增加一倍。 -
很抱歉选错了词。我认为这将是“双重”,因为它使用了两次递归。