题目一:求斐波那契数列第n项
自己所写代码如下:
#include "stdafx.h" #include<iostream> long Fibonacci(unsigned int N) { long F0 = 0; long F1 = 1; if(N == 0) return F0; else if(N == 1) return F1; else { int n = 2; while(n <= N) { F0 = F0 + F1; F1 = F0 + F1; n += 2; } return (N % 2 == 0)? F0 : F1; } } int main() { int N = 10; for(int i=0; i<=N; i++) { long FValue = Fibonacci(i); std::cout<<FValue<<std::endl; } return 0; }
虽然知道可以用递归实现,但实际写代码却有些生疏,关键是对递归不是很熟练。。。
参考作者代码,基于递归的实现如下:
long Fibonacci(unsigned int n) { int results[2] = {0,1}; //递归终止条件 if(n < 2) return results[n]; return Fibonacci(n-1) + Fibonacci(n-2); }
递归代码相当简洁!但正如书中所说,用递归求解斐波那契数列的第n项,会由于有很多重复的子问题求解,比如求解f(10)时,会求解两次f(8),因而造成计算复杂度随着n的增大而急剧增加!因此,该题用递归解并不是一种好的选择!时间复杂度:O(2_^n),即以n为指数的增长。
作者所写基于循环的实现如下:(很规范)
long Fibonacci(unsigned int n) { int results[2] = {0,1}; if(n < 2) return results[n]; long Fib_0 = results[0]; long Fib_1 = results[1]; long Fib_i; for(int i=2; i <= n; i++) { Fib_i = Fib_0 + Fib_1; Fib_0 = Fib_1; Fib_1 = Fib_i; } return Fib_i; }
和自己所写的代码,思想一致!时间复杂度:O(n)。
该题时间复杂度可以达到O(logn),只做了解了。
题目二:(关于斐波那契数列的应用)
青蛙跳台阶,每次只能跳1个台阶或者2个台阶,则问青蛙若要跳n个台阶共有多少种跳法?
分析:该题的思路不太好想。。。
首先要想到以n为变量,n个台阶的跳法共有f(n)种,那么:
分析一:到第n-1阶后,再跳一步即到第n阶,此时的跳法为f(n-1);
到第n-2阶后,再跳一个两步或者连续跳一步即可到第n阶,但此时注意到后者包含在上一步中,所以此时的跳法为f(n-2),而非2*f(n-2)。
分析二:以开始跳为分界点更好些。
第一跳若为跳一步,则剩下的n-1台阶的跳法为f(n-1);
第一跳若为跳一个两步,则剩下的n-2台阶的跳法为f(n-2);
避免 对分析一中特殊情况的忽略。
综上,n个台阶的跳法f(n)=f(n-1)+f(n-2)为斐波那契数列!!!