当前位置: 首页 > 知识库问答 >
问题:

了解递归如何使用多个返回

羊城
2023-03-14

下面的问题来自于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;

共有2个答案

仲孙钊
2023-03-14

除了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
蓝苗宣
2023-03-14

基本上功能可以分解为:

>

  • 如果“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万以下的哪个