70. Climbing Stairs
思路:递归 --> memo --> DP
斐波那契数列:
- 公式:
public int climbStairs(int n) {
int a = 1, b = 1;
for (int i = 0; i < n; i++) {
a = (b = b + a) - a;
}
return a;
}
- Recursion && memorization:
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
memo = [-1 for i in range(n + 1)]
def cb(n):
if n == 0 or n == 1:
return 1
if memo[n] == -1:
memo[n] = cb(n - 1) + cb(n - 2)
return memo[n]
return cb(n)
- DP:
递推式:f(n) = f(n - 1) + f(n - 2)
的意思举例来说,当n = 4
时,f(4) = f(3) + f(2)
代表从三级台阶可以跳一级到达四级,也可以从二级台阶跳两级跳到四级,所以结果为两数之和。注意java中n过大结果会溢出。
public int climbStairs(int n) {
int[] memo = new int[n + 1];
memo[0] = memo[1] = 1;
for (int i = 2; i <= n; i++) {
memo[i] = memo[i - 1] + memo[i - 2];
}
return memo[n];
}
变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
和之前普通跳台阶的递推式差不多,比如
f(4) = f(3) + f(2) + f(1) // 四级台阶可以由三级,二级,一级台阶跳上来
f(3) = f(2) + f(1) // 三级可以由二级,一级台阶跳上来
--------------------------
f(4) = 2 * f(3)
由等比数列递推式推出f(n) = 2 ^ (n - 1) * f(1)
又因为f(1) = 1
所以f(n) = 2 ^ (n - 1)
public int climbStairsII(int target) {
return 1 << target - 1;
}
矩形覆盖
我们可以用2*1
的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1
的小矩形无重叠地覆盖一个2*n
的大矩形,总共有多少种方法?
n
0 ---> 0
1 ---> 1
2 ---> 2
3 ---> 3
4 ---> 5
public int RectCover(int target) {
if (target == 0) return 0;
int a = 1, b = 1;
while (target-- > 0) {
a = (b += a) - a;
}
return a;
}