一、题目描述
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
二、解题思路
(标有相同数字的为一个小矩形)
n=1:1种
[0]
[0]
n=2:2种
[0][1] [0][0]
[0][1] [1][1]
n=3:3种
[0][1][2] [0][0][2] [0][1][1]
[0][1][2] [1][1][2] [0][2][2]
n=4:5种
[0][1][2][3] [0][0][2][3] [0][1][1][3] [0][1][2][2] [0][0][2][2]
[0][1][2][3] [1][1][2][3] [0][2][2][3] [0][1][3][3] [1][1][3][3]
…
如上不难看出是一个斐波那契数列。
问题也可以这样理解,用第一个2*1小矩阵覆盖大矩形的最左边时有两个选择:
1)当竖着放时,右边还剩下2*(n-1)的区域。
2)当横着放时,左上角放一个2*1横着的小矩形,左下角必须也横着放一个2*1的小矩形,而此时右边还剩下2*(n-2)的区域。
因此F(n)=F(n-1)+F(n-2)。
因为递归方法计算的时间复杂度是以n的指数的方式递增的。所以用单纯的循环,创建一个ArrayList,将每次的RectCover(n)值记录。
三、编程实现
import java.util.ArrayList;
public class Solution {
public int RectCover(int target) {
// if (target <= 2) {
// return target;
// }
// return RectCover(target - 1) + RectCover(target - 2);
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i <= target; i++) {
if (i <= 2) {
list.add(i);
} else {
list.add(list.get(i - 1) + list.get(i - 2));
}
}
return list.get(list.size() - 1);
}
}