矩形覆盖:递归和迭代实现

矩形覆盖


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

题目来自《剑指Offer》,经过跳台阶和变态跳台阶的摧残,我发现这种题目就是找规律的过程,知道了怎么个规律之后,一切就好说了
首先你可以举例子从n比较小的时候去发现规律,但是从n为5开始,要完整的列出所有的方法,思维难度已经开始提升了一个档次,不过你可以从前四个看出它确实很像斐波那契数列,但是这些只能用于猜测,具体推理过程如下:

  1. 假设覆盖2*n的大矩形有f(n)种方法;
  2. 当n<=0的时候,有0种方法;
  3. 当n=1的时候,只有1种方法;
  4. 当n=2的时候,有2种方法;
  5. 当n>2的时候,放置第一块2*1的小矩形有两种可能(横着和竖着);
  6. 横着放的时候,我们可以把剩下的空格看成需要覆盖2*(n-1)的大矩形,即有f(n-1)种方法;
  7. 竖着放的时候,小矩形占了2格长,其旁边的剩下2格长只能竖着放一个小矩形,此时剩下n-2行,即覆盖一个2*(n-2)的大矩形,有f(n-2)种方法;
  8. 综上,n>2时,f(n)=f(n-1)+f(n-2);

代码递归实现如下:

public class Solution {
    public int RectCover(int target) {
        if (target <= 0)
            return 0;
        if (target == 1) 
            return 1; 
        if (target == 2)
      		return 2;
        return RectCover(target-1) + RectCover(target-2);
    }
}

但是,如果你利用递归解决问题,开销会很大,而且测试用例中肯定准备了一个很大的n让你运行超时,所以想要顺利通过我们得利用迭代的方法
代码迭代实现如下:

public class Solution {
    public int RectCover(int target) {
        if(target <= 0) return 0;
        if(target == 1) return 1;
        if(target == 2) return 2;
        int one = 1;
        int two = 2;
        int result = 0;
        for(int i = 2; i < target; i++){
            result = one+ two;
            one = two;
            two = result;
        }
        return result;
    }
}

你可能感兴趣的:(数据结构与算法)