【算法】Fibonacci常规·记忆华搜索·动态规划

博客介绍了计算Fibonacci的三种方法适用的数据量范围。常规方法适用于n取值1 - 50,记忆化搜索适用于n取值1 - 5000,动态规划适用于n取值1 - 50000。

三种方法分别适用的数据量范围(即n的取值)如下
常规:1-50
记忆华搜索:1-5000
动态规划:1-50000

package com.demo;

import java.math.BigInteger;

public class Fibonacci {
	
	public static long[] memo = new long[123457];
	
	/**
	 * 常规:斐波那契 
	 * 下面代码的特点,两个return
	 * 用 int 作为返回值的原因是这种方法根本算不了多少数就顶不住了,
	 * 数据量大一点就慢的要命了,再大一点就爆栈了
	 * 所以int 范围就够了
	 */
	public static int fibo(int n) {
		if(n==1 || n==2)  
			return 1;
		return fibo(n-1)+fibo(n-2); 
	}
	
	
	/**
	 * 记忆化搜索:斐波那契
	 * 下面代码的特点,两个return,夹一个递归赋值操作 
	 * 用 long 作为返回值的原因是这种方法虽然能很快的算很多数,
	 * 但数据量再大一点就爆栈了
	 * 所以long 范围就够了
	 */
	public static long memoFibo(int n) {
		if(n == 1 || n == 2)  
			return 1;
		if(memo[n] == 0) // 代表 fibo(n) 未被计算过   
			memo[n] = memoFibo(n-1)+memoFibo(n-2); 
		return memo[n];
	}
	/**
	 * 动态规划:斐波那契 
	 * 下面代码的特点,内部申请数组,for循环计算,一个return
	 * 之所以是一个return,区别于上面两个return,就是因为此方法不是递归,不需要递归结束条件
	 * 用BigInteger作为返回值的原因是这种方法能算很多数,
	 * 数据量可以撑到Java堆内存不足
	 * 所以使用BigInteger
	 */
	public static BigInteger dpFibo(int n) {
		BigInteger[] memory = new BigInteger[n+1];
		memory[1] = BigInteger.valueOf(1);
		memory[2] = BigInteger.valueOf(1);
		for(int i=3; i<=n; i++) // 注意结束条件是小于等于
			memory[i] = memory[i-1].add(memory[i-2]); // 注意索引是i不是n
		
		return memory[n];
	}
	
	
	public static void main(String[] args) {
		
		int n = 20;
		
		// n > 45 时会很慢
		long s = System.nanoTime();
		int res = fibo(n);
		long e = System.nanoTime();
		
		// n > 1w 时虽然很快,但long越界,再大就会爆栈
		long sMemo = System.nanoTime();
		long resMemo = memoFibo(n);
		long eMemo = System.nanoTime();
		
		// n > 10w 时会java.lang.OutOfMemoryError: Java heap space
		long sDp = System.nanoTime();
		BigInteger resDp = dpFibo(n);
		long eDp = System.nanoTime();
		
		
		System.out.println(res+"fibo用时:"+(e-s)/1000+"μs");
		System.out.println(resMemo+"memoFibo用时:"+(eMemo-sMemo)/1000+"μs");
		System.out.println(resDp+"dpFibo用时:"+(eDp-sDp)/1000+"μs");
		
	}

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值