题目要求
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:2
示例 2:
输入:n = 7
输出:21
示例 3:
输入:n = 0
输出:1
提示:
0 <= n <= 100
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof
下面展示的解法代表了我对题目的处理思路——首先是最直观的递归,当然时间超限不符合出题人的要求,那么就想着将递归写成动态规划,并且在此基础上尽量做出优化。
一、递归
和前面斐波那契数列一样,这种类型的题目第一时间想到的就是递归的做法:每次只能跳一阶或者两阶,所有跳到第n个台阶的方法可以看作是跳到第n-2阶的方法加上跳到第n-1阶的方法。
代码如下:
int numWays(int n) {
if (n == 0 || n == 1) {
return 1;
}
return (numWays(n-1) + numWays(n-2))%1000000007;
}
当然,不是出题人预想的解答,超出时间限制,考虑动态规划的做法。
二、动态规划
改动态规划比较简单,可以用一个数组容器承载所有欲计算项,解决了递归的重复计算的问题(递归的另一个问题是递归层数太高可能会导致栈溢出)。
代码如下:
int numWays(int n) {
if (n == 0) {
return 1;
}
vector<int> v(n+1,0);
v[0] = v[1] = 1;
for (int i = 2; i < n+1; ++i) {
v[i] = (v[i-1] + v[i-2])%1000000007;
}
return v[n];
}
同样,还可以从空间的角度对代买进行进一步优化,即不借助辅助数组空间。
三、空间优化
int numWays(int n) {
int v[3] = {1, 1, 2};
for (int i = 1; i < n/3+1; ++i) {
v[0] = (v[1] + v[2])%1000000007;
v[1] = (v[2] + v[0])%1000000007;
v[2] = (v[0] + v[1])%1000000007;
}
return v[n%3];
}
总结
与斐波那契数列完全一样思路的题目,没有什么特别的感想。