一个斐波那契数列的变体面试题

题目: 有一堆数量为N的球,一次只能从球堆中拿一个或者拿两个球,问把球拿完总共有多少种取法。

先举个例子说明一下问题,例如球堆中有3个球,那么取法有三种:
  • 1,1,1
  • 1,2
  • 2,1


乍一看和斐波那契没啥关系,当时直接把这道题当高中排列组合做了-。-’ 经过提醒才反过味儿来。

解法1:递归法。

感觉算法的精髓在于。。。。你得经历过这种算法,毕竟如果没经过训练/经历我觉得很难把自己的思维直接定位在正确的跑道上的,听说那些搞ACM都是经过大量训练的,就跟高考前不停地做卷子一个道理。

然后回到题目,取N个球的取法F(N),其实可以分为以下两种情况

第一种情况是最后一次(拿完就没了的这一次)只取到了一个球,那么实际上这种取法正好是F(N-1),即N-1个球的取法。
第二种情况是最后一次取到了两个球。那么这种取法是F(N-2)。

结论:可以得到F(N)=F(N-1)+F(N-2),即斐波那契数列。递归的结束条件是N为0时返回0,N为1时返回1,N为2时返回2(1,1;2两种取法).

解法2:排列组合。

正因为高中做这种题多了,首先就用这种想法来解决问题了。解法如下:
先用一个实体数字来代替N吧,这样容易理解,比如N=6.

那么,最极端的两种情况,要么每次都拿1,要么每次都拿2,这样都是只有一种取法。
1,1,1,1,1,1
2,2,2

接下来,可以用穷举法,想象每次取2个球的这种情况从0次到最大次数的过程,
所有的过程中取1次2,那么肯定取了4次1;问题变成了,现在有4个1,1个2,请问有几种取法,结果是C5,4==C5,1==5
所有的过程中取2次2,那么肯定取了2次1;问题变成了,现在有2个2,2个1,请问有几种取法,结果是C4,2==6

∴(左侧这个字符屌爆)最终的结果是1+1+5+6=13

可以从N=6推导到所有的情况,其实就是在取2的次数为0到取2的次数最大这个过程中,排列组合的累和,可以通过循环获得。


猜你喜欢

转载自wwwcomy.iteye.com/blog/2366605