題目來源:牛客網-劍指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;
}
}
如果本文對你有所幫助,要記得點贊哦~