分治法面試題(一):矩形覆蓋


關於分治法

  分治法,分而治之。就是將原問題划分為n個規模較小,結構與原問題類似的小問題進行處理,遞歸地解決這些問題,然后再合並求解的過程。

  分治法在解決的流程上分為三個步驟:

  1.分解:將原問題划分為n個規模較小,結構與原問題類似的小問題。

  2.解決:若子問題規模小,足以處理,則求解,否則繼續遞歸處理。

  3.合並:將子問題的解,合並成為原問題的解。

面試題:矩形覆蓋

  我們可以用2*1的小矩形橫着或者豎着去覆蓋更大的矩形。請問用number個2*1的小矩形無重疊地覆蓋一個2*number的大矩形,總共有多少種方法?

  分析:我們化繁為簡,從下面的示例說起(設該問題的處理函數為rectCover)。

  由於小矩形的尺寸是2×1,所以有大矩形為2×number的存在,那么我們第一步就可以有兩種處理方式:

  第一步如果選擇豎方向填充,那么該問題的規模就縮減為對於剩余的2×(number-1)的大矩形的填充。

  如果,第一步如果選擇橫方向的填充,則第二排的前面兩個小矩形也只能如此填充,那么該問題的規模就縮減為對於剩余的2×(number-2)的大矩形的填充.

  結合上述分析,很容易得到遞推的關系: rectCover(number)=rectCover(number-1)+rectCover(number-2)。當然此處也要注意遞歸跳出條件的判定。

  下面是對應的算法

 1 class Solution {
 2 public:
 3     int rectCover(int number) {
 4     if(number<=0) return 0;
 5         if(number==1) return 1;
 6         if(number==2) return 2;
 7         else
 8             return rectCover(number-1)+rectCover(number-2);
 9     }
10 };

  當然,遞歸的實現必須借助棧,而且存在很多重復計算的數據。不妨取number=5,遞推的過程如下。可以看出rectCover(3)計算2次,rectCover(2)計算3次,rectCover(1)計算2次。所以遞歸的效率比較低下,下篇 動態規划法面試題(一):矩形覆蓋會繼續探討這個問題,給出另一種“高效”的解法。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM