题目描述
我们可以用2 * 1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2 * 1的小矩形无重叠地覆盖一个2 * n的大矩形,从同一个方向看总共有多少种不同的方法?
比如n=3时,2*3的矩形块有3种不同的覆盖方法(从同一个方向看):
算法思路
这题的解题思路和斐波那契数列以及跳台阶问题一模一样
斐波那契数列
跳台阶
这道题的难点在于你并不容易发现它是斐波那契数列,所以我们一开始可以尝试用找规律的方式去找到解题思路
当 n = 1 时,只有1种
当 n = 2 时,有2种
当 n = 3 时,有3种
当 n = 4 时,有5种
从而可以发现递推公式:
f(n) = f(n-1) + f(n-2) (n>=3)
代码实现
递归
public class Solution {
public int rectCover(int target) {
if(target <= 2){
return target;
}
return rectCover(target-1)+rectCover(target-2);
}
}
时间复杂度:O(2n)
空间复杂度:O(1)
动态规划
public class Solution {
public int rectCover(int target) {
if(target<=1){
return target;
}
int[] dp= new int[target+1];
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
for(int i=3;i<=target;i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[target];
}
}
时间复杂度:O(n)
空间复杂度:O(n)
优化存储空间
public class Solution {
public int rectCover(int target) {
if(target<=2){
return target;
}
int sum = 0;
int one = 1;
int two = 2;
for(int i=3;i<=target;i++){
sum = one + two;
one = two;
two = sum;
}
return sum;
}
}
时间复杂度:O(n)
空间复杂度:O(1)