【问题标题】:Order of execution in a recursive call递归调用中的执行顺序
【发布时间】:2019-12-20 11:26:07
【问题描述】:

当一个返回命令有两个递归调用时,例如 return fib(n-1) + fib(n-2);,是两个调用同时执行,还是fib(n-1)fib(n-2)之前执行?

通过使用记忆,时间复杂度降低到 O(n),但不是只有在 fib(n-1)fib(n-2) 之前执行(然后使用存储值)才有可能吗?

*public int fib(int n)是一种使用递归计算第N个斐波那契数的方法。

【问题讨论】:

  • 评估顺序为 LTR。对记忆无关紧要;该值要么存在于缓存中,要么不存在。提示:fib(n-1) 下一步调用什么?此外,解决斐波那契的记忆是缓慢的、低效的、过于复杂的,并且由于许多其他原因是一个 Bad Idea TM。
  • 什么是 LTR?但是,对于要显示的值,它必须事先计算(因为 fib(n-1) 调用 fib(n-2),当使用 memoization 并且不再计算 fib(n-2) 时)。我正在尝试以这种方式解决它,因为我正在练习动态编程,而任何其他问题对我来说似乎都太难/太模糊了。

标签: java recursion dynamic-programming memoization


【解决方案1】:

Java guarantees 表示表达式中子表达式的求值顺序是从左到右。

Java 编程语言保证运算符的操作数看起来是按照特定的求值顺序进行求值的,即从左到右。

这意味着fib(n-1) 将在fib(n-2) 之前被评估。

但是评估顺序并没有改变这里记忆的复杂性,无论哪种方式,它仍然是 O(n)。当 Java 对其进行评估时,fib(n-1) 将通过n-1 完成所有备忘录值,包括fib(n-2) 的值。对fib(n-2) 的调用没有任何作用;它只是引用了已经计算的值fib(n-1)

如果你颠倒了代码中的顺序:

fib(n-2) + fib(n-1)

然后将首先调用fib(n-2),这将完成通过n-2 的所有备忘录值。然后对fib(n-1) 的调用将使用现有的记忆值来“完成”通过fib(n-1) 完成所有值的工作。

无论哪种方式,在评估这些表达式之后,通过n-1 的所有值都会被记忆,具有 O(n) 的(最坏情况)时间复杂度(和空间复杂度)。这也可能是调用fib(n) 的结果,这会另外记住n 的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    相关资源
    最近更新 更多