斐波那契数列
最简单的递归法:
存在大量的重叠子问题,时间复杂度为 ,很慢,会超时。
class Solution {
public:
int Fibonacci(int n) {
if(n==0 or n==1) return n;
return Fibonacci(n-1) + Fibonacci(n-2);
}
};
动态规划: 直接从子树求得答案,过程是从下往上,时间复杂度:O(n),空间复杂度:O(n)
class Solution {
public:
int Fibonacci(int n) {
if(n==0 or n==1) return n;
int a{0}, b{1}, c;
for(int i=2; i<=n; i++){
c = a + b;
a = b;
b = c;
}
return c;
}
};
青蛙跳台阶
题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
分析:
假设 表示跳上第 个台阶的方法数,而第n个台阶可以是由第n-1个台阶跳上的,也可以是由第n-2个台阶跳上的,所以方法数 ,且初始条件 f[1] = 1,f[2] = 2. 本质上还是斐波那契数列。不再附代码了。
变态跳台阶
题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
分析:
假设 表示跳上第 个台阶的方法数,求 。
假设现在已经跳到了第 n 个台阶,那么前一步可以从哪些台阶到达呢?
- 如果上一步跳 1 步到达第 n 个台阶,说明上一步在第 n-1 个台阶,而跳到第n-1个台阶的方法数为f[n-1];
- 如果上一步跳 2 步到达第 n 个台阶,说明上一步在第 n-2 个台阶,而跳到第n-2个台阶的方法数为f[n-2];
- 。。。
- 如果上一步跳 n-1 步到达第 n 个台阶,说明上一步在第 1 个台阶。已知跳到 第1个台阶的方法数为f[1] = 1
- 如果上一步跳 n 步到达第 n 个台阶,说明上一步在第 0 个台阶。已知跳到 第0个台阶的方法数为f[0] = 0
那么总的方法数就是所有可能的和:f[n] = f[n-1] + f[n-2] + … + f[1]
显然初始条件还是 f[1] =1, f[2] = 2
继续分析:
f[n] = f[n-1] + f[n-2] + … + f[1], 那么 f[n-1] 呢?
显然,f[n-1] = ff[n-2] + … + f[1]
原来如此:f[n] = f[n-1] × 2
继续分析:
累乘法:
f[n] = f[n-1] × 2
f[n-1] = f[n-2] × 2
…
f[3] = f[2] × 2 = 2 × 2
所以:f[n] = pow(2, n-1)
return pow(2, n-1);
return 1 << (n-1);