剑指offer 跳台阶,变态跳台阶,矩形覆盖

题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

思路:台阶数:1,2,3,4,5

              跳法:1,2,3,5,8

显然的菲波那切数列

答题思路

  1. 如果只有1级台阶,那显然只有一种跳法
  2. 如果有2级台阶,那么就有2种跳法,一种是分2次跳。每次跳1级,另一种就是一次跳2级
  3. 如果台阶级数大于2,设为n的话,这时我们把n级台阶时的跳法看成n的函数,记为f(n),第一次跳的时候有2种不同的选择:一是第一次跳一级,此时跳法的数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1),二是第一次跳二级,此时跳法的数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2),因此n级台阶的不同跳法的总数为f(n) = f(n-1) + f(n-2),不难看出就是斐波那契数列

数学函数表示如下

f(x)=\left\{ \begin{aligned} & 0 & n=0 \\ & 1 & n=1 \\ & 2 & n=2 \\ & f(n-1)+f(n-2) & n > 2 \end{aligned} \right.

public class Solution {
    public int JumpFloor(int target) {
        if(target==0 || target==1 || target==2)
            return target;
        else
            return JumpFloor(target-1)+JumpFloor(target-2);
    }
}

题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

思路:台阶数:1,2,3,4,5

              跳法:1,2,4,8,16

显然后面数字是前面的两倍

思路

  1. 如果台阶级数为n的话,这时我们把n级台阶时的跳法看成n的函数,记为f(n),第一次跳的时候有n种不同的选择:若是第一次跳一级,此时跳法的数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1),若是第一次跳m(m<n)级,此时跳法的数目等于后面剩下的n-m级台阶的跳法数目,即为f(n-m),若是第一次跳n级,此时跳法的数目等于1.所以 f(n) = f(n-1) + f(n-2) + ... + f(n-m) + ... + f(2) + f(1) + 1
  2. 因此f(n - 1) = f(n-2) + ... + f(n-m) + ... + f(2) + f(1) + 1
  3. 两式相减得到 f(n) = 2 * f(n-1)
  4. 因此可以得到下面的结果
    \begin{aligned} f(n) &= f(n-1) + f(n-2) + ... + f(n-m) + ... + f(2) + f(1) + 1 \\ &= 1 + f(1) + f(2) + ... + f(n-m) + ... + f(n-2) + f(n-1) \\ &= 1 + f(1) + 2*f(1) + ... + 2^{n-m-1} * f(1) + ... 2^{n-3} * f(1) + 2^{n-2} * f(1) \\ &= 1 + 1 + 21 + ... + 2^{n-m-1} + ... 2^{n-3} + 2^{n-2} \\ &= 2^{n-1} \end{aligned}
public class Solution {
    public int JumpFloorII(int target) {
        if(target==0 || target==1)
            return target;
        else
            return JumpFloorII(target-1)*2;
    }
}

题目描述

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

思路:
我们采用从能够简单到复杂的思路思考这个问题,当n=1的时候,只有一个2*1的矩形,所以只有一种方法,记为f(1)=1;当n=2的时候,是两个2*1的矩形,这时候具有两种方式去覆盖这个矩形了(这时候应该是一个正方形),一种是竖着放,一种是横着放,所以有两种方法,记为f(2)=2;

当n=3的时候,仍然只能采用横着放或者竖着放的方式去覆盖这个矩形,我们仍首先考虑使用竖着放的方式,当竖着放的时候,由于已经覆盖了左边(假设是从左边开始覆盖的,从右边的覆盖的效果是一样的)一个2*1的矩形,所以还有2个2*1的矩形,而这种情况我们已经在n=2的时候计算出来了,就是f(2);接下来我们考虑横着放的情况,由于是横着放,在水平方向已经覆盖了一个2*1的矩形,所以要想覆盖这由3个2*1组成的矩形,只能在水平方向的覆盖的那个矩形下面继续覆盖一个,那么只剩下一个2*1的矩形了,这也通过前面的分析计算出来了,就是f(1)。综合以上分析,当n=3的时候,覆盖的方法是f(3)=f(1)+f(2)。
 

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

猜你喜欢

转载自blog.csdn.net/w584212179/article/details/87891469
今日推荐