题目来源:牛客网-剑指Offer专题
题目地址:矩形覆盖
题目描述
我们可以用的小矩形横着或者竖着去覆盖更大的矩形。请问用n个的小矩形无重叠地覆盖一个的大矩形,总共有多少种方法?
比如n=3时,的矩形块有3种覆盖方法:
题目解析
其实这类题目,如果实在不知道怎么下手,都不妨先考虑枚举,将前面小的数先枚举出来,然后再猜测规律是什么。一般可以考虑的式子有 、斐波那契数列、n相关的多项式、组合数、卡特兰数、欧拉函数……
这看这道题,我们先把 比较小的情况先枚举出来,如下表所示:
n | 1 | 2 | 3 | 4 | 5 | 6 | … |
---|---|---|---|---|---|---|---|
result | 1 | 2 | 3 | 5 | 8 | 13 | … |
看,不骗你们吧!这不是斐波那契数列吗?我不是坑你们,只是在实在无从下手的时候给你们提供一种思路,别动不动就写什么搜索去枚举这些情况……
下面是正解时间:
参考了讨论区中Follow大佬的讲解思路,假设我们有一个 的大矩形,当 时的方法有 种,我们先考虑第一个 小矩形的摆法。有下面两种情况:
- 情况一:如下图竖着摆放,那么剩下的矩形就形成了一个 的大矩形,所以这种情况下的覆盖方法有 种。
* | |||||||
---|---|---|---|---|---|---|---|
* |
- 情况二:如下图横着摆放,为了把它下方的空间覆盖,第二个 小矩形也必须横着摆在它的下方,,那么剩下的矩形就形成了一个 的大矩形,所以这种情况下的覆盖方法有 种。
* | * | ||||||
---|---|---|---|---|---|---|---|
- | - |
于是,我们就可以知道 ,再结合 的情况,我们就可以得到以下的递推式啦~
这个递推式看烂了,这里就简单写常用的两种实现方式,详情可以参考上篇博客解法:斐波那契数列(四种解法)。
方法一:
面试别写型递推版实现,时间复杂度 。
public class Solution {
public int RectCover(int n) {
if (n < 3) {
return n;
}
return RectCover(n - 1) + RectCover(n - 2);
}
}
方法二:
面试推荐型,自底向上型循环求解,时间复杂度为 。
public class Solution {
public int RectCover(int n) {
if (n == 0) return 0;
int a = 1, b = 1;
for (int i = 1; i < n; i++) {
a = a + b;
b = a - b;
}
return a;
}
}
如果本文对你有所帮助,要记得点赞哦~