【算法导论学习-28】Fibonacci数列及其相关
来源:互联网 发布:视频解码软件 编辑:程序博客网 时间:2024/06/08 05:54
1、解决方案
Fibonacci数列增长很快,第100个已经到了10的20次方,64位计算机才表示到19次方。所以这里统一采用计算第40个数来比较性能。实际上,4个字节的int类型只能计算到第48个Fibonacci数(以0、1、1、2开头)为1836 311 903,一个18亿左右的数字。
1)递归方法——写法简单,效率非常低下
public class Fibonacci { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 long start=System.nanoTime(); //获取开始时间 int fibonacciNO=getFibonacci(40); long end=System.nanoTime(); //获取结束时间 System.out.println("程序运行时间: "+(end-start)+"ns"); System.out.println(fibonacciNO); } /* 递归方案 */ public static int getFibonacci(int n) { if (n == 1) { return 0; } else if (n == 2) { return 1; } else { return getFibonacci(n - 1) + getFibonacci(n - 2); } }}******************************************************************
输出:程序运行时间: 687841156ns
63245986
2)动态规划方法——写法简单,非常高效,复杂度O(n)
思路:算法导论370页课后题15.1-5,符合动态规划的一个特性——当前问题调用了两个子问题。
public class Fibonacci { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 long start=System.nanoTime(); //获取开始时间 int[] fibonacciNO=getFibonacci(40); long end=System.nanoTime(); //获取结束时间 System.out.println("程序运行时间: "+(end-start)+"ns"); for (int i : fibonacciNO) { System.out.println(i); } } /*自底向上进行计算*/ public static int[] getFibonacci(int n) { int[] temp=new int[n]; temp[0]=0; temp[1]=1; for (int i = 2; i < n; i++) { temp[i]=temp[i-1]+temp[i-2]; } return temp; }}*****************************************
程序运行时间: 5131ns
63245986
3)通项公式方法——投机取巧,比较低效
思路:算法导论59页
public class Fibonacci { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 long start=System.nanoTime(); //获取开始时间 System.out.println(getFibonacci(40)); long end=System.nanoTime(); //获取结束时间 System.out.println("程序运行时间: "+(end-start)+"ns"); } public static int getFibonacci(int i) { float root=(float) ((1+Math.sqrt(5))/2); return (int) Math.round(Math.pow(root, i)/Math.sqrt(5)); } }*****************************************
控制台输出:
102334197
程序运行时间: 655532ns
2、相关的数学问题
1)排列组合
有一段楼梯有10级台阶,规定每一步只能跨一级或两级,要登上第10级台阶有几种不同的走法?
这就是一个斐波那契数列:登上第一级台阶有一种登法;登上两级台阶,有两种登法;登上三级台阶,有三种登法;登上四级台阶,有五种登法……
1,2,3,5,8,13……所以,登上十级,有89种走法。
2)数列中相邻两项的前项比后项的极限
当n趋于无穷大时,F(n)/F(n+1)的极限是多少?
这个可由它的通项公式直接得到,极限是(-1+√5)/2,这个就是黄金分割的数值,也是代表大自然的和谐的一个数字。
3、【一道面试题】如何判断一个数是不是Fibonacci数?(我的一点思路,还没有找到最终答案)
讨论区:http://bbs.csdn.net/topics/120067216
1)在数比较小的时候(小于20724)
A verynice test is that N is a Fibonacci number if and only if 5 n^2 + 4 or 5n^2 – 4 is a squarenumber.
即判断5 n^2 + 4 or 5n^2 – 4 是否是完全平方数,这里引出一个算法问题:“如何判断一个数是完全平方数?”,参考http://blog.sina.com.cn/s/blog_5a4882970102dxa5.html。这里主要讲完全平方数必然是连续奇数和:1+3+5+7+....+(2*n-1)=n^2。
public class Fibonacci { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 long start=System.nanoTime(); //获取开始时间 int[] fibonacciNO=getFibonacci(48); long end=System.nanoTime(); //获取结束时间 System.out.println("程序运行时间: "+(end-start)+"ns"); for (int i : fibonacciNO) { System.out.print(isFibonacciNo(i)); } } /*是否是Fibonacci数*/ public static boolean isFibonacciNo(int n) { /*5 n^2 + 4如果大于Integer.MAX_VALUE则表明无法做判断了*/ if (n>Math.pow((Integer.MAX_VALUE-4)/5, 0.5)) { System.out.print("无法判断——"); return false; } int temp=(int) (5*Math.pow(n, 2)); return isPerfectSquareNo(temp+4)||isPerfectSquareNo(temp-4); } /*完全平方数的判断*/ public static boolean isPerfectSquareNo(int n) { for (int i = 1; n >0; i+=2) { n-=i; } return n==0; } /*自底向上进行计算*/ public static int[] getFibonacci(int n) { int[] temp=new int[n]; temp[0]=0; temp[1]=1; for (int i = 2; i < n; i++) { temp[i]=temp[i-1]+temp[i-2]; } return temp; }}***********************************************
程序测试表明,4个字节的int类型能只能判断到(int)Math.pow((Integer.MAX_VALUE-4)/5, 0.5)),大约20724,即最多可以判断2万个数而已。
2)、在数字比较大的情况下(整个Int长度内判断)
思路1
使用动态规划方法生成Fibonacci数列,直到生成的Fibonacci数列等于n返回true,大于n返回false。
思路2
。。。。待续,绝对应该有比较高效的算法。。。。。
- 【算法导论学习-28】Fibonacci数列及其相关
- Fibonacci 数列及其计算方法
- Fibonacci数列问题算法
- Fibonacci数列 算法
- Fibonacci 数列算法
- 算法之数列 Fibonacci
- Fibonacci数列-递归算法
- Fibonacci数列算法分析
- Fibonacci数列的相关问题
- Fibonacci数列及相关问题
- fibonacci数列的矩阵算法
- 每日一算法:Fibonacci数列
- 经典算法之Fibonacci数列
- 算法基础:递归---Fibonacci数列
- 蓝桥杯算法 入门 Fibonacci数列
- Fibonacci数列算法Java版
- 网易算法题--Fibonacci数列
- 算法学习笔记(3)——分治法,Fibonacci数列,Strassen算法
- Android发送接收短信的代码示例(本人验证OK)
- HDU 2795——Billboard(线段树)
- python链接oracle数据库
- 多线程互斥与同步
- 可怕的中国人逻辑缺陷,你了解多少?
- 【算法导论学习-28】Fibonacci数列及其相关
- C语言可变参数的实现机制
- Firefox中文件下载JS
- eclipse 各个版本的比较
- 【DP】UVA 10651 Pebble Solitaire 记忆化搜索
- Codeforces 132C. Logo Turtle
- [Dahua Lin] Computer Vision的尴尬
- 晶振参数校定
- IOS开发常用工具网站地址