我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,从同一个方向看总共有多少种不同的方法?
数据范围:
进阶:空间复杂度
,时间复杂度 %5C)
进阶:空间复杂度
注意:约定 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)
代码:
public class Solution { public int rectCover(int target) { if(target <= 1){ return 1; } if(target*2 == 2){ return 1; }else if(target*2 == 4){ return 2; }else{ return rectCover((target-1))+rectCover(target-2); } } }