题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。To do it!
示例1 输入: n = 2,输出: 2
示例2 输入: n = 7,输出: 21
示例3 输入: n = 0,输出: 1
提示: 0 <= n <= 100
题解
此题与上一题 斐波那契数列 基本一致,唯一不同的是起始状态不同。
- 青蛙跳台阶问题:f(0) = 1, f(1) = 1, f(2) = 2;
- 斐波那契数列问题:f(0) = 0, f(1) = 1, f(2) = 1.
记忆递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Solution { vector<int> ans; const int mod = 1000000007; int f(int n) { if (n < 2) return 1; if (ans[n] == 0) ans[n] = (f(n - 1) + f(n - 2)) % mod; return ans[n]; } public: int numWays(int n) { ans = vector<int>(n + 1, 0); return f(n); } };
|
时间复杂度:O(n),空间复杂度:O(n)
动态规划
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { private: const int MOD = 1000000007; public: int numWays(int n) {
if (n < 2) return 1; int a = 1, b = 1, c = 2; for (int i = 3; i <= n; i++) { a = b; b = c; c = (a + b) % MOD; } return c; } };
|
时间复杂度:O(n),空间复杂度:O(1)
矩阵快速幂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class Solution { private: const int MOD = 1000000007; vector<vector<long>> multiply(vector<vector<long>>& a, vector<vector<long>>& b) { vector<vector<long>> c{{0, 0}, {0, 0}}; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { c[i][j] = (a[i][0] * b[0][j] + a[i][1] * b[1][j]) % MOD; } } return c; }
vector<vector<long>> pow(vector<vector<long>>& a, int n) { vector<vector<long>> ret{{1, 0}, {0, 1}}; while (n > 0) { if (n & 1) { ret = multiply(ret, a); } n >>= 1; a = multiply(a, a); } return ret; } public: int numWays(int n) { if (n < 2) return 1; vector<vector<long>> M{{1, 1}, {1, 0}}; vector<vector<long>> res = pow(M, n - 1); return (res[0][0] + res[0][1]) % MOD; } };
|
时间复杂度:O(log n),空间复杂度:O(1)