如何解决使用大整数时间复杂度的递归斐波那契数列
你能解释一下下面算法的复杂性吗?
public BigInteger fibBigInt() {
return fibBigInt(
BigInteger.valueOf(n),ONE,BigInteger.valueOf(0));
}
private BigInteger fibBigInt(BigInteger start,BigInteger val,BigInteger previous) {
if (start.compareTo(BigInteger.valueOf(0)) == 0) {
return previous;
}
return fibBigInt(
start.subtract(ONE),val.add(previous),val);
}
这个递归是如何在 O(n) 时间内运行的?我有点糊涂了。
解决方法
Fibonacci 是不同复杂度类别的标准示例,因为根据定义,天真的方法需要 O(2^n)
时间,而线性解决方案只需要 O(n)
时间。这个适用于线性模式。
这个想法是有一个起始值(fib(0)
和 fib(1)
)并通过一次调用它从 fib(n+2)
迭代计算 fib(n+1)
。诀窍是不仅存储来自 fib(n+1)
的结果,还存储来自 fib(n)
的结果。这是通过在每个递归步骤中“旋转”fib(n+1)
和 fib(n)
的值来完成的。
因此最好通过示例 (n
=5) 来解释其工作原理。请注意,参数 m
是您想要的斐波那契数的输入值。 m
值递减,值 0 标志着递归结束。您截取的代码使用计数器 m
运行并且没有属性 n
。
n |
m |
fib(n+1) |
fib(n) |
评论 |
---|---|---|---|---|
0 | 5 | 1 | 0 | 代码的前 6 行 |
1 | 4 | 1+0 = 1 | 1 | 迭代步骤,代码的最后 4 行。当前的 fib(n+1) 是上一行中的 fib(n+1) +fib(n) ,fib(n) 是上一行中的 fib(n+1) 。 |
2 | 3 | 1+1 = 2 | 1 | 见上 |
3 | 2 | 2+1 = 3 | 2 | |
4 | 1 | 3+2 = 5 | 3 | |
5 | 0 | 5+3 = 8 | 5 | 现在术语 start.compareTo(BigInteger.valueOf(0)) 变为 0,因此 fib(n) (5) 的值将通过每次递归调用返回并“转发”回来。 |
这种方法显然是线性的,因此在 O(n)
中运行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。