开宗明义:本系列基于牛客网剑指offer,刷题小白,一天两道我快乐!旨在理解和交流,重在记录,望各位大牛指点!
牛客网-剑指offer
1、变态跳台阶
描述:一只青蛙一次可以跳1级台阶,也可以跳2级,甚至可以跳n级台阶,求该青蛙跳上一个 n 级台阶总共有多少种跳法。
思路:推导动态规划的公式:
- n台阶梯,第一步有 n n n 种跳法,1,2—n;
- 跳一级,剩下 n − 1 n-1 n−1 级,剩下的跳法是 f ( n − 1 ) f(n-1) f(n−1);
- 再跳一级,剩下 n − 2 n-2 n−2 级,剩下的跳法是 f ( n − 2 ) f(n-2) f(n−2);
- 所以 f ( n ) = f ( n − 1 ) + f ( n − 2 ) + f ( n − 3 ) + . . . + f ( 2 ) + f ( 1 ) f(n)=f(n-1)+f(n-2)+f(n-3)+...+f(2)+f(1) f(n)=f(n−1)+f(n−2)+f(n−3)+...+f(2)+f(1);
- 上述式子可得到: f ( n ) = 2 ∗ f ( n − 1 ) f(n)=2*f(n-1) f(n)=2∗f(n−1);
测试代码:
class Solution {
public:
int jumpFloorII(int number) {
if (number == 0) {
return 1;
}
if (number == 1) {
return 1;
}
return 2 * jumpFloorII(number - 1);
}
};
2、矩形覆盖
描述:用 2 ∗ 1 2*1 2∗1 的小矩形横着或竖着去覆盖更大的矩形。请问用 n n n 个 2 ∗ 1 2*1 2∗1 的小矩形无重叠地覆盖一个 2 ∗ n 2*n 2∗n 的大矩形,总共多少办法?
思路:数学归纳法,找规律。
- 当 n < 1 n<1 n<1 时,返回0;
- 当
n
=
1
n=1
n=1 时,返回1;
- 当
n
=
2
n=2
n=2 时,返回2;
- 当
n
=
3
n=3
n=3 时,
- 当 n = 4 n=4 n=4 时,…我们可以猜到 f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n)=f(n-1)+f(n-2) f(n)=f(n−1)+f(n−2)。
- 将题目改成
1
∗
3
1*3
1∗3 方块覆盖
3
∗
n
、
1
∗
4
3*n、1*4
3∗n、1∗4 方块覆盖
4
∗
n
4*n
4∗n。
相应的结论应该是:
(1) 1 ∗ 3 1 * 3 1∗3 方块覆盖 3 ∗ n 3*n 3∗n 区域: f ( n ) = f ( n − 1 ) + f ( n − 3 ) , ( n > 3 ) f(n) = f(n-1) + f(n - 3), (n > 3) f(n)=f(n−1)+f(n−3),(n>3)
(2) 1 ∗ 4 1 *4 1∗4 方块覆盖 4 ∗ n 4*n 4∗n 区域: f ( n ) = f ( n − 1 ) + f ( n − 4 ) , ( n > 4 ) f(n) = f(n-1) + f(n - 4),(n > 4) f(n)=f(n−1)+f(n−4),(n>4)
更一般的结论,如果用 1 ∗ m 1*m 1∗m 的方块覆盖 m ∗ n m*n m∗n 区域,递推关系式为 f ( n ) = f ( n − 1 ) + f ( n − m ) , ( n > m ) f(n) = f(n-1) + f(n-m),(n > m) f(n)=f(n−1)+f(n−m),(n>m)。
测试代码:
class Solution {
public:
int rectCover(int number) {
if (number < 1) {
return 0;
}
if (number == 1 || number == 2) {
return number;
}
return rectCover(number-1) + rectCover(number-2);
}
};