我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,从同一个方向看总共有多少种不同的方法?
数据范围:
进阶:空间复杂度 ,时间复杂度
进阶:空间复杂度 ,时间复杂度
注意:约定 n == 0 时,输出 0
比如n=3时,2*3的矩形块有3种不同的覆盖方法(从同一个方向看):
2*1的小矩形的总个数n
覆盖一个2*n的大矩形总共有多少种不同的方法(从同一个方向看)
0
0
1
1
4
5
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # 分析:https://uploadfiles.nowcoder.com/images/20160616/716804_1466088939214_DB8DE8E90C58DADF4C1048A7B110E8E5 # 这个题是斐波那契数列,分析可以看上面的大神的分析,我没想起来。 # 应该用递归实现 ,但是python递归太慢 超时,应该用非递归实现: if number == 0: return 0 f0 = 0 f1 = 1 NEXT = 0 i = 0 while i < number: NEXT = f0 +f1 # 下一个值 是前两个的和 f0 = f1 # f0 往前走一步 f1 = NEXT # f1 往前走一步 i += 1 return NEXT
其实就是简单的斐波那契数列, f(n) = f(n-1) + f(n-2),
因此无论是用递归法或者直接法都很简单。但是递归效率很低。
class Solution {
public:
//方法一:递归,代码简单,但是耗时长,约500ms
int rectCover(int number) {
if(number <= 2) return number;
else return rectCover(number-1) + rectCover(number-2);
}
//方法二:非递归,复杂度低,速度快,只要3ms
int rectCover(int number) {
if(number <= 2) return number;
int a=1, b=2, cnt = 2;
while(cnt < number)
{
b += a;
a = b - a;
cnt ++;
}
return b;
}
};
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
public class Solution { public int rectCover(int target) { if(target<=2){ return target; } int pre=1; int cur=2; for(int i=3;i<=target;i++){ cur+=pre; pre=cur-pre; } return cur; } }
public class Solution { public int rectCover(int target) { if (target < 1) { return 0; } else if (target == 1 || target == 2) { return target; } else { return rectCover(target-1) + rectCover(target-2); } } }
public int rectCover(int target) { //target == 1 时,只有竖放的一种可能; //target == 2 时,再 2 * 2 大矩形中有横放和竖放两种方法; …… if (target <= 2){ return target; } return rectCover(target - 1) + rectCover(target - 2); }
第一次摆放一块1*2的小矩阵,则摆放方法总共为f(target-2)
代码: