tags:
- 简单
- 完成
- 数组
- 斐波那契数列
- 动态规划
flag: green
style: summer
data: ‘2019-6-10’
509.斐波那契数
一、题目
斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
给定 N,计算 F(N)。
-
示例 1:
输入:2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1. -
示例 2:
输入:3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2. -
示例 3:
输入:4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3. -
提示:
0 ≤ N ≤ 30
二、解答
整体方案: 迭代和递归或者动态规划
- 动态规划:
不能使用递归f(n) = f(n-1) + f(n-2)的原因:会造成大量重复计算,导致时间复杂度为O(2^n)。
使用动态规划消除重复计算,可使时间复杂度优化至O(n)。可用数组保存计算结果,则空间复杂度为O(n)。此处进一步简化,只使用两个变量保存结果,因此空间复杂度为O(1)。
class Solution {
public int fib(int N) {
int curr = 0, next = 1;
while(N-- > 0) {
next = next + curr;
curr = next - curr;
}
return curr;
}
}
作者:scvthedefect
链接:https://leetcode-cn.com/problems/two-sum/solution/dong-tai-gui-hua-by-scvthedefect/
- 递归和迭代的比较
递归时间久但不需要额外空间, 迭代时间少, 但需要额外空间
/**
* 迭代
* @param N 位置
* @return int
*/
public int fib(int N) {
int[] fib = new int[N + 2];
fib[0] = 0;
fib[1] = 1;
if (N < 2) return fib[N];
for (int i = 2; i <= N; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
return fib[N-1] + fib[N-2];
}
/**
* 递归
* @param N 位置
* @return int
*/
public int fib2(int N) {
if (N == 1) return 1;
if (N == 0) return 0;
return fib(N - 1) + fib(N - 2);
}
作者:nza
链接:https://leetcode-cn.com/problems/two-sum/solution/die-dai-huo-zhe-di-gui-by-pepsi-3/
个人解法:递归
class Solution {
public int fib(int N) {
if (N == 0) {
return 0;
}else if (N == 1) {
return 1;
}else{
return fib(N - 1) + fib(N - 2);
}
}
}
执行用时 : 14 ms, 在Fibonacci Number的Java提交中击败了37.92% 的用户
内存消耗 : 31.8 MB, 在Fibonacci Number的Java提交中击败了96.00% 的用户