剑指Offer #10 矩形覆盖(问题分析)

题目来源:牛客网-剑指Offer专题
题目地址:矩形覆盖

题目描述

我们可以用212*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个212*1的小矩形无重叠地覆盖一个2n2*n的大矩形,总共有多少种方法?

比如n=3时,232*3的矩形块有3种覆盖方法:
1

题目解析

其实这类题目,如果实在不知道怎么下手,都不妨先考虑枚举,将前面小的数先枚举出来,然后再猜测规律是什么。一般可以考虑的式子有 2n12^{n-1} 、斐波那契数列、n相关的多项式、组合数、卡特兰数、欧拉函数……

这看这道题,我们先把 nn 比较小的情况先枚举出来,如下表所示:

n 1 2 3 4 5 6
result 1 2 3 5 8 13

看,不骗你们吧!这不是斐波那契数列吗?我不是坑你们,只是在实在无从下手的时候给你们提供一种思路,别动不动就写什么搜索去枚举这些情况……


下面是正解时间:

参考了讨论区中Follow大佬的讲解思路,假设我们有一个 2n2*n 的大矩形,当 n=in=i时的方法有 f(i)f(i) 种,我们先考虑第一个 212*1 小矩形的摆法。有下面两种情况:

  • 情况一:如下图竖着摆放,那么剩下的矩形就形成了一个 2(n1)2*(n-1) 的大矩形,所以这种情况下的覆盖方法有 f(n1)f(n-1) 种。
*
*
  • 情况二:如下图横着摆放,为了把它下方的空间覆盖,第二个 212*1 小矩形也必须横着摆在它的下方,,那么剩下的矩形就形成了一个 2(n2)2*(n-2) 的大矩形,所以这种情况下的覆盖方法有 f(n2)f(n-2) 种。
* *
- -

于是,我们就可以知道 f(n)=f(n1)+f(n2)f(n)=f(n-1) + f(n-2),再结合 n20n-2 \leq0 的情况,我们就可以得到以下的递推式啦~

f(n)={1,n=12,n=2f(n1)+f(n2),n>2 f(n)= \begin{cases} 1&, \text{n=1} \\ 2 &,\text{n=2} \\ f(n-1) + f(n-2) &,\text{n>2} \end{cases}

这个递推式看烂了,这里就简单写常用的两种实现方式,详情可以参考上篇博客解法:斐波那契数列(四种解法)

方法一:
面试别写型递推版实现,时间复杂度 O(2n)O(2^n)

public class Solution {
    public int RectCover(int n) {
        if (n < 3) {
            return n;
        }
        return RectCover(n - 1) + RectCover(n - 2);
    }
}

方法二:
面试推荐型,自底向上型循环求解,时间复杂度为 O(n)O(n)

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;
    }
}

如果本文对你有所帮助,要记得点赞哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章