下面的问题来自于CodingBat:给定一个数组,是否可以选择一组整数,使其与给定的目标相加?
站点作者提供了以下解决方案:
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;
}
假设我想尝试下面的例子,其中nums=[2,4,8]并调用groupSum(0,nums,10)。
我看到groupsum(0,nums,10)
将调用groupsum(1,nums,10)
和groupsum(1,nums,8)
。
Groupsum(1,nums,10)
调用Groupsum(2,nums,10)
和Groupsum(2,nums,6)
Groupsum(1,nums,8)
调用Groupsum(2,nums,8)
和Groupsum(1,nums,4)
等等。
在处理代码时,我看到了以下调用:
groupSum(3,nums,10)
groupSum(3,nums,2)
groupSum(3,nums,6)
groupSum(3,nums,-2)
groupSum(3,nums,8)
groupSum(3,nums,0)
groupSum(3,nums,4)
groupSum(3,nums,-4)
我看到groupsum(3,nums,0)
应该返回true,因为第一行:if(start>=nums.length)return(target==0);
,但我对其他调用感到困惑,如groupsum(3,nums,-4)
。由于target!=0
,从第一行开始,它应该清楚地导致false。
另外,有人能解释一下为什么return true语句在
if (groupSum(start + 1, nums, target - nums[start])) return true;
我以为第一行就能决定真假。
if (groupSum(start + 1, nums, target)) return true;
除了Kolink在Java的详细漫步之外,我还创造了这张照片来帮助我看到:
public class TestRecursion{
public static boolean groupSum(int start, int[] nums, int target, String s) {
System.out.println(new String(new char[start]).replace("\0", " ")+"start="+start+" target="+target+" parent="+s);
if (start >= nums.length) return (target == 0);
if (groupSum(start + 1, nums, target - nums[start], "A:"+start+"_"+target)) return true;
if (groupSum(start + 1, nums, target, "B:"+start+"_"+target)) return true;
return false;
}
public static void main(String... args){
int[] nums = {2,4,8};
groupSum(0, nums, 10, "");
}
}
输出:
start=0 target=10 parent=
start=1 target=8 parent=A:0_10
start=2 target=4 parent=A:1_8
start=3 target=-4 parent=A:2_4
start=3 target=4 parent=B:2_4
start=2 target=8 parent=B:1_8
start=3 target=0 parent=A:2_8
基本上功能可以分解为:
>
如果“start”(数字数组中的当前位置)是数组末尾的一部分(换句话说,如果我们已经尝试了所有的数字),则如果达到目标(即为零),则函数成功
否则,继续使用包含的当前数字(target-nums[start]
)迭代(start+1
),如果有效,则返回true
否则,包含当前数字不起作用,所以继续迭代而不包含当前数字。如果有效,则返回true
如果我们已经做到了这一点,那么就没有办法添加起作用的数字,所以返回false
。
您已经分解了所有可能的函数调用的步骤,正如您所观察到的,有一个返回true(其中target为零)。这个true
结果级联将递归备份为最终返回值。
以下是其工作原理的粗略分类:
groupSum(0,[2,4,8],10)
0 >= 3? no, so continue:
groupSum(1,[2,4,8],10-2)?
1 >= 3? no, so continue:
groupSum(2,[2,4,8],8-4)?
2 >= 3? no, so continue:
groupSum(3,[2,4,8],4-8)?
3 >= 3? yes. -4 == 0? no, return false
groupSum(3,[2,4,8],4)?
3 >= 3? yes. 4 == 0? no, return false
return false
groupSum(2,[2,4,8],8)?
2 >= 3? no, so continue:
groupSum(3,[2,4,8],8-8)?
3 >= 3? yes. 0 == 0? yes, return true
yes, return true
yes, return true
yes, return true
希望这有帮助!
假设我有n个list<T>的集合 比如 List<shool>、List<Det>、List<Student>..... for循环做法 foreacher(var item in List<shool>) { } 最终输出为字典 存储的是第一个为 拿这三个举例 shool_0 det_0 student_0 第二个为 shool 0 det 0 student 1 目前我的想法是递归 但是这边递
问题内容: 我在上面直接写了上面的内容,因此可能无法编译,但认为可以。 任何人都可以从存储的角度来简短地解释它的工作原理吗?它通过计算5 (5-1)开始,然后依次下降到4 (4-1)然后是3 *(3-1).....直到达到1,它将只返回1,对吗?抱歉,我太粗略了,我只想知道这是如何工作的 谢谢 但随着工作的进行,它将获得各个阶段的值 5 (5-1)4 (4-1)… … … 这些如何存储然后取回,或
我试图了解如何将各种递归函数转换为尾递归。我已经查看了许多将斐波那契和阶乘转换为尾递归的示例,并理解了这些示例,但很难跳到具有某种不同结构的问题。一个例子是: 如何将其转换为尾部递归实现? 我已经看过类似的问题,例如:将正常递归转换为尾部递归,但这些似乎并没有转化为这个问题。
问题内容: 我在这里找到了一个很棒的树指令。原文:http://jsfiddle.net/n8dPm/ 我一直在试图通过其他几个做题,要了解它的功能。我不太明白呈现树指令的递归调用是如何工作的。主要是编译功能 什么时候所有的编译函数都调用? $ compile函数何时被缓存在变量中(这是链接函数吗?),何时追加?为什么不总是附加? - 问题答案: Ng网站上有一些很棒的文档(我认为是最好的文档)。
为了概括这个问题,我借用了Zelenski CS课堂讲义中的材料。而且,这与我的具体问题有关,因为几年前我从另一位讲师那里学习了C语言的这种方法。讲义在这里。我对C的理解很低,因为我偶尔使用它。基本上,我需要编写一个程序的几次,我回到课堂材料,找到类似的东西,然后从那里开始。 在本例(第4页)中,Julie正在字符串函数中使用递归算法查找单词。为了减少递归调用的数量,她添加了一个决策点。 为了增加
Project Euler问题14给出以下问题: 为正整数集定义以下迭代序列: n→n/2(n为偶数) n→3n 1(n为奇数) 使用上述规则,从13开始,我们生成以下序列: 13→ 40→ 20→ 10→ 5.→ 16→ 8.→ 4.→ 2.→ 1. 可以看出,该序列(从13开始,到1结束)包含10个术语。虽然这还没有被证明(科拉兹问题),但人们认为所有的起始数字都以1结束。 100万以下的哪个