当使用leetcode 70爬楼梯时:你正在爬楼梯。到达顶部需要n步。每次爬1或2步。您可以通过多少不同的方式登顶? 这是我的第一个解决方案:
class Solution {
public int fib (int n){
if (n <= 2) return n;
return fib(n-1) + fib(n-2);
}
public int climbStairs(int n) {
return fib (n+1);
}
}
当n <44时,它有效,但是n> = 44,它不起作用。因此,它导致了leetcode中的提交失败。 但是当使用第二种解决方案时,显示如下
class Solution {
public int climbStairs(int n) {
if (n <= 2) return n;
int[] allWays = new int[n];
allWays[0] = 1;
allWays[1] = 2;
for (int i = 2; i < n; i++){
allWays[i] = allWays[i-1] + allWays[i-2];
}
return allWays[n-1];
}
}
第二个解决方案被leetcode接受。但是,当n> = 46时,它给出一个负数。
任何人都可以解释为什么第一个解决方案失败了吗?这两种解决方案之间的区别是什么?感谢。
答案 0 :(得分:0)
要了解解决方案,您需要了解Dynamic Programming
和Recursion
在第一个计算第n个Fibonacci数的解决方案中,你的算法是
fib(n)= fib(n-1)+fib(n-2)
但第二种解决方案更加优化
此方法将值存储在数组中,这样您就不必每次都计算fib(n)
。
示例:
fib(5) = fib(4) + fib(3)
= (fib(3) + fib(2)) + (fib(2) + fib(1))
通过第一个解决方案,您在n = 4时计算两次fib(2)。
通过第二种解决方案,您将fibonacci值存储在数组中
实施例: 对于n = 4,
首先计算fib(2) = fib(1)+fib(0) = 1
然后你计算f(3) = f(2)+f(1)
我们不必计算the fib(2)
,因为它已经存储在数组中。
答案 1 :(得分:0)
你的直觉是正确的。达到顶峰的方式确实遵循斐波纳契序列。
第一个解决方案递归计算斐波纳契数(fib(n) = fib(n - 1) + fib(n-2)
)。要计算任何值,函数需要递归调用自身两次。每个函数调用占用称为堆栈的内存区域中的空间。可能发生的事情是当n太大时,会发生太多递归调用,并且程序空间不足以执行更多调用。
第二种解决方案使用动态编程和memoization。这有效地节省了空间和计算时间。如果您不了解这些主题,我建议您阅读它们。
由于第47个Fibonacci数大于类型int
可以表示的最大值,因此得到负值。您可以尝试使用long
或BigInteger
类来表示更大的值。