这是我参与更文挑战的第 5 天,活动详情查看: 更文挑战
斐波那契数列
题目描述
写一个函数,输入 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:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示
0 <= n <= 100
思路分析
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。感觉这种题目就是为递归而生的,大问题分解为多个子问题,子问题和父问题的解法逻辑一直,因为是从 0 和 1 开始,所以 0 和 1 就是终止条件。
递归解法我们可以使用备忘录解法进行优化,将计算过的值存入到数组中,如果已经计算过该表达式的值,直接从数组中取值即可。
同时我们也可以使用动态规划解法,动态的改变几个临时变量的值,优化计算时间。
代码展示
解法一:时间复杂度是,空间复杂度是。
int[] mem = new int[101];
public int fib(int n) {
return fib_r(n);
}
public int fib_r(int n) {
if (n == 0){
return 0;
}
if (n <= 2){
return 1;
}
if (mem[n] != 0){
return mem[n];
}
mem[n] = (fib_r(n-1) + fib_r(n-2)) % 1000000007;
return mem[n];
}
解法二:时间复杂度是,空间复杂度是。
public int fib(int n) {
if (n == 0){
return 0;
}
if (n <= 2){
return 1;
}
int a = 1;
int b = 1;
int c = 0;
for (int i = 3; i <= n; i++) {
c = (a + b) % 1000000007;
a = b;
b = c;
}
return c;
}
a,b,c 的值在每次循环后进行一次变换,最终得到最后的值。
青蛙跳台阶问题
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:2
示例 2:
输入:n = 7
输出:21
提示
0 <= n <= 100
思路分析
青蛙每次可以跳上1级台阶,也可以跳上2级台阶,也就是说只有这两种跳法,比如输入 n = 3,可以分解为连续跳三次一级台阶和两次(一次跳一级台阶,一次跳二级台阶,顺序不同,跳法不同),所以一共有 3 中跳法。n 可以分解为 n -1 和 n - 2 解法的和。
所以我们也就推出了我们的递归公式,终止条件是 n = 1 和 n = 2。需要注意的是 n = 0 是,返回值为 1,也就是说什么都不用跳,直接返回。
递归解法我们可以使用备忘录解法进行优化,将计算过的值存入到数组中,如果已经计算过该表达式的值,直接从数组中取值即可。
第二种解法是动态规划,我们可以动态地改变几个临时变量的值,大大地优化计算时间。
代码展示
解法一:时间复杂度是,空间复杂度是。
int[] cache = new int[101];
public int numWays(int n) {
if (n == 0){
return 1;
}
if (n == 1){
return 1;
}
if (n == 2){
return 2;
}
if (0 != cache[n]){
return cache[n];
}
cache[n] = (numWays(n-1) + numWays(n-2)) % 1000000007;
return cache[n];
}
解法二:时间复杂度是,空间复杂度是。
public int numWays(int n) {
if (n == 0){
return 1;
}
if (n == 1){
return 1;
}
if (n == 2){
return 2;
}
int a = 1;
int b = 2;
int c = 0;
for (int i = 3; i <=n ; i++) {
c = (a + b) % 1000000007;
a = b;
b = c;
}
return c;
}
a,b,c 的值在每次循环后进行一次变换,最终得到最后的值。
总结
斐波那契数列和青蛙跳台阶是典型的递归题目,解题者很容易想到递归解法,通过备忘录解法进行优化,同时我们也可以动态规划进行解答该题,不断的变化变量的值,返回最终的值。最后还要进行一个最大值越界处理。