递归算法斐波那契数列

递归算法Q1——斐波那契数列

有一对兔子,从出生后第3个月起,每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子。
假如兔子都不死,求第n个月兔子对数
关于斐波那契数列的兔子繁殖问题其实如下:
实际月份  1    2    3    4    5    6    7     8
幼仔对数  1    0    1    1    2    3    5     8
成兔对数  0    1    1    2    3    5    8    13
总体对数  1    1    2    3    5    8   13    21
幼仔对数=前月成兔对数
成兔对数=前月成兔对数+大前月幼仔对数
总体对数=本月成兔对数+本月幼仔对
package 递归;

public class 斐波那契数列 {
	//上楼梯的递推式与斐波那契数列一样也为f(n)=f(n-1)+f(n-2)
	//n fib(n)
	//1 1 1 2 3 
	//2 1 2 3 5
	//3 2
	//4 3
	//5 5
	/**递归
	 * 存在重复计算
	 * @param n
	 * @return
	 * 时间复杂度:O(2^n) 尝试按照T(n)=T(n-1)+T(n-2)+O(1)去推 失败了
	 * 空间复杂度:对应搜索二叉树 O(n)
	 */
	int fib0(int n) {
		if(n<=2) return 1;
		return fib0(n-2)+fib0(n-1);
	}
	
	/**
	 * @param n
	 * @return
	 * 用数组fib存储计算过的fib(n)值  每一个值对应的fib(n)只被计算一次
	 * 时间复杂度:O(n)
	 * 空间复杂度:O(n)
	 */
	int fib1(int n) {
		//规模小于2直接返回值
		if(n<=2)  return 1;
		int [] nums=new int[n+1];
		return fib1(n,nums);
	}
	/**
	 * @param n
	 * @param nums
	 * @return
	 * 空间复杂度:O(n)
	 * 时间复杂度:O(n)
	 */
	int fib1(int n,int []nums) {
		if(n<=2) return 1;//递归出口
		if(nums[n]==0) {//说明n对应的fib值没有计算过
			nums[n]=fib1(n-1,nums)+fib1(n-2,nums);
		}
		return nums[n];
	}
	
	int fib2(int n) {
		if(n<=2) return 1;
		int []fib=new int[n+1];
		fib[1]=fib[2]=1;
		for(int i=3;i<=n;i++) {
			fib[i]=fib[i-1]+fib[i-2];
		}
		return fib[n];
	}
	
	//0//	1 1 3 3
	//1//	1 2 2 5
	/**
	 * @param n
	 * @return
	 * 每次运算只需用到数组中的两个元素 所以使用滚动数组
	 * 时间复杂度:O(n)
	 * 空间复杂度:O(1)
	 * 
	 */
	int fib3(int n) {
		if(n<=2) return 1;
		int []fib=new int[n];
		fib[0]=fib[1]=1;
		for(int i=3;i<=n;i++) {
			//i=3 	1 0 1
			//4		0 1 0
			//5   	1 0 1	  
			fib[i&1]=fib[(i-1)&1]+fib[(i-2)&1];
		}
		return fib[n&1];
	}
	//两变量
	int fib4(int n) {
		if(n<=2) return 1;
		int first=1;
		int second=1;
		for(int i=3;i<=n;i++) {
			//	f(1)+f(2)
			first=first+second;		//2 3 5
			second=first-second; 	//1 2
		}
		return first;
	}
	//三变量
	int fib5(int n) {
		if(n<=2) return 1;
		int first=1;
		int second=1;
		int third=0;
		for(int i=3;i<=n;i++) {
			third=first+second;
			first=second; 	
			second=third; 	
		}
		return third;
	}
	public static void main(String[] args) {
		斐波那契数列 a=new 斐波那契数列();
		System.out.println(a.fib0(6));
		System.out.println(a.fib1(6));
		System.out.println(a.fib2(6));
		System.out.println(a.fib3(6));
		System.out.println(a.fib4(6));
		System.out.println(a.fib5(6));
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值