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

如果本文對你有所幫助,要記得點贊哦~

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