1.1、题目
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下: F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
1.2、思路
做法1【记忆化搜索】:用数组或map把计算的结果保存起来,下次来需要计算的话先判断是否已经计算过、若是已经计算过、返回已计算的的结果。【用数组或者Hashmap记录已计算的结果】
做法2、自底向上【动态规划】
初始a=f(0)=0,b=f(1)=1,c=f(2)
按照此顺序递推
1.3、代码
1、自上而下做法
1.1、用数组保存已经计算过的结果;
时间复杂度O(n),空间O(n),递归n次
class Solution {
int []arr;
public int fib(int n) {
// 初始化一个数组来保存结果
arr = new int[n+1];
for (int i = 0; i < n+1; i++) {
// -1表示没有计算过
arr[i]=-1;
}
return f(n);
}
int f(int n){
// 递归结束条件
if(n<=1){
return n;
}
// 判断是否计算过
if(arr[n]!=-1){
return arr[n];
}
// 计算结果并取模
int sum = (f(n-1)+f(n-2))%1000000007;
// 将结果保存起来
arr[n]=sum;
return sum;
}
}
1.2 、用Hashmap来保存已计算过的结果
class Solution {
Map<Integer,Integer> hashMap = new HashMap<>();
public int fib(int n) {
if (n <2) {
return n;
}
// 若已计算过、直接返回结果
if (hashMap.get(n) != null) {
return hashMap.get(n);
}
int sum = (fib(n-1)+fib(n-2)) % 1000000007;
// 保存已计算的结果
hashMap.put(n,sum);
return sum;
}
}
2、动态规划
class Solution {
public int fib(int n) {
// 递归出口
if (n <2){
return n;
}
int a = 0;
int b = 1;
int c = -1;
for(int k=2; k<=n; k++) {
c = (a+b) % 1000000007;
a = b;
b = c;
}
return c;
}
}
最好结果
2. 青蛙跳台阶问题
2.1、题目
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n
级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
提示:
0 <= n <= 100
2.2、分析:
若有n个台阶:
如果第一次跳1阶:剩下n-1阶,则剩下f(n-1)种跳法。
如果第一次跳2阶段:剩下n-2阶,则剩下f(n-2)种跳法。
因此f(n)=f(n-1)+f(n-2)种跳法。
又f(0)=1,f(1)=1;
2.3、代码
class Solution {
public int numWays(int n) {
// 递归出口
if (n <2){
return 1;
}
int a = 1;
int b = 1;
int c = a+b;
for(int k=2; k<=n; k++) {
c = (a+b) % 1000000007;
a = b;
b = c;
}
return c;
}
}