问题(问题大全)

今天在网上看到两个算法题,分别是跳青蛙问题与变态跳青蛙问题,具体题目如下。

问题(问题大全)

跳青蛙问题:

这道题看似简单,但是我看了半天也没想出个突破口,在本子上画来画去也没想到解决的方法。

直到我将台阶的个数于跳法的个数罗列出来才发现端倪:

 

这尼马不就是斐波那彻数列么?

这下问题转变成了,如何求斐波那彻数列?

方法分两种:递归和非递归。

其实递归的方法是更加容易理解的,写起来也是最简单的。我们直到斐波那彻数列的公式:

套用公式就能写出递归的方法:

关于递归方法时间复杂度,这里就不做研究了,有兴趣的朋友可以看看这篇博客,讲的非常好,因为我看不懂:

http://www.cnblogs.com/python27/archive/2011/12/09/2282486.html

其实递归方法的效率是非常慢的,如果在面试的时候,明明可以用非递归的方法写出答案,你偏偏要用递归,那你就是做死了(真事儿,我朋友面别人就用这标准)。

下面介绍非递归的方法,先来看看代码:

很明显,时间复杂度为O(n),比递归的方法快了很多倍。

这种方法巧妙的利用了求解公式,类似于用了两个指针,分别指向了被求数的前两位数,得到被求数后,再将其值赋予其中一个指针,另一个指针则往前挪。

看过了正常的跳青蛙问题,我们再来看变态的跳青蛙。

具体题目如下:

套用吴宗宪大哥的话说就是:哎哟,这个就厉害了。

这次青蛙可以任意的选择跳上的台阶数,所以不再是一个标准的斐波那契数列问题,不过没关系,我们先找寻问题的规律,再从规律寻找突破口。

根据题目,有:

f(0) = 1

f(1) = 1

f(2) = f(2-1) + f(2-2)

f(3) = f(3-1) + f(3-2) + f(3-3)

...

f(n) = f(n-1) + f(n-2) + ... + f(n-(n-1)) + f(n-n)

简单的解释一下:例如f(3-1)表示3阶跳了1阶后,剩下的跳阶方法数,f(3-2)表示3阶跳了两阶后剩下的跳阶方法数,以此类推,直到一次跳n阶后,剩下的跳阶方法数。

现在问题明了了很多,但是还不够,我们可以继续对其进行分解:

因为 : f(n) = f(n-1) + f(n-2) + ... + f(n-(n-1)) + f(n-n) = f(0) + f(1) + f(2) + ... + f(n-2) + f(n-1)

所以 : f(n-1) = f(0) + f(1) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + ... + f(n-2)

则: f(n) = f(n-1) + f(n-1) = 2*f(n-1)

现在可以根据这个式子来写出代码了。

同样,我们先写出容易写的递归方法:

然后是非递归的方法:

通过对这两个问题的分析和解决,我深刻的明白了一个道理:解决问题之前,我们必须充分的了解问题,把握问题的规律。科学家们一直致力于寻找物质的规律,世界的规律以及宇宙的规律。而算法的美妙之处就在于,你通过不断的训练,能从纷杂的问题表面分析出实质性的规律,就如同在茫茫互联网海洋中,寻找那一段段神秘的代码。

今天的博客就写道这里了,老司机催我上车了。

 

转载请说明出处 内容投诉内容投诉
九幽软件 » 问题(问题大全)