【剑指offer】斐波那契数列(续)

来源:互联网 发布:都市淘宝修道 编辑:程序博客网 时间:2024/06/10 04:40

题目描述

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


  首先我们考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。

  现在我们再来讨论一般情况:我们把 n 级台阶时的跳法看成是 n 的函数,记为 f(n) 。当 n > 2 时,第一次跳的时候就有两种不同的选择:一是第一次只跳 1 级,此时跳法数目等于后面剩下的 n - 1 级台阶的跳法数目,即为 f(n-1);另外一种选择是第一次跳 2 级,此时跳法数目等于后面剩下的 n-2 级台阶的跳法数目,即为 f(n-2)。

  因此 n 级台阶时的不同跳法的总数 f(n) = f(n-1) + f(n-2)。
我们把上面的分析用一个公式总结如下:

   ┌ 1      , ( n=1 )
f(n) = ┤ 2      , ( n=2 )
   └ f(n-1) + (f-2), ( n>2 )

  分析到这里,我们不难看出这实际上就是斐波那契数列了。
代码见【剑指offer】斐波那契数列


题目描述

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


同样我们定义 f(n) 为 n 级台阶跳法的数量
分析如下:
n = 1 时,1 种跳法,f(1) = 1;
n = 2 时,2 种跳法:一次跳1级,或者一次跳2级,f(2) = 2;
n > 2 时
  将所有的 n 级台阶的完成分成两个部分来看,第一部分:跳一次;第二部分:用各种方法跳到顶点。
第一步如果跳 1 级,那么剩下 n - 1 级台阶,那么第二步总共会有 f(n-1) 种跳法;
第一步如果跳 2 级,那么剩下 n - 2 级台阶,那么第二步总共会有 f(n-2) 种跳法;
……
第一步如果跳 n-2 级,那么剩下 2 级台阶,那么第二步总共会有 f(2) = 2 种跳法;
第一步如果跳 n-1 级,那么剩下 1 级台阶,那么第二步总共会有 f(1) = 1 种跳法;
第一步如果跳 n 级,那么就直接上顶,没有第二步了;

  也就是说,第一步总共是有 n 种可能的跳法,每种可能的跳法执行后,都会有不同的第二步跳法。那么把所有第二步可能的跳法全部加起来,就构成了所有的跳法 f(n) 。

即:
f(n) = f(n - 1) + f(n - 2) + f(n - 3) + … + f(2) + f(1) + 1
f(n - 1) = f((n - 1) - 1) + f((n - 1) - 2) + … + f(2) + f(1) + 1
    = f(n - 2) + f(n - 3) + … + f(2) + f(1) + 1
所以 f(n) = 2f(n - 1)
故可得

   ┌ 1    , ( n=0 )
f(n) = ┤ 1    , ( n=1 )
   └ 2 * f(n-1), ( n>=2 )
那么代码可以这样写:

public int jump(int n) {    if (n <= 0) {        return -1;    } else if (n == 1) {        return 1;    } else {        return 2 * jump(n - 1);    }}

但是,以上的解法并不优雅。我们不妨换个角度想,在一次成功地跳上顶部后,这所有的 n 个台阶都会存在两种状态,即:被跳了,或者没被跳。(除了最上面一个台阶必须跳上去,其状态为”被跳了”)其他的 n - 1 个台阶的状态都可能是这两种状态任意之一。因此,总的可能的跳法数为 2^( n - 1) 。而涉及到2的 n 次幂的计算,必先考虑用位运算符来实现。即 2^( n - 1) = 1 << ( n - 1) ,或者 1 << - - n 。


题目描述

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


我们把总共的方法数看成是 n 的函数,记为 f(n) 。
易得 f( 1 ) = 1, f( 2 ) = 2
当 n > 2 时,第一个小矩形摆放在大矩形最左边时有两种摆法,横着放或者竖着放,如果竖着放,右边剩下 2*( n - 1) 的大矩形,摆放方法数为 f( n - 1);如果横着放在左上角,那么左下角必须横着放一个同样的小矩形,此时,右边剩下 2*( n - 2) 的大矩形,摆放方法数为 f( n - 2),因此 f( n ) = f( n - 1) + f( n - 2),这还是一个斐波那契数列。: )

n个2*1的小矩形无重叠地覆盖一个2*n的大矩形

原创粉丝点击