斐波那契数列问题 --- 动态规划法

题目描述:

求斐波那契数列中的第n个值

斐波那契数列:{1, 1, 2, 3, 5, 8, 13, 21…}
输入:n — 你想要求的数

分析:

  1. 当 n == 1时, fib(n) = 1
  2. 当 n == 2时, fib(n) = 1
  3. 当 n > 2 时, fib(n) = fib(n - 1) + fib(n - 2)

递归法:

public class FeiBoNaQieShuLie {
	private static int[] fib;
	
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		int n = input.nextInt();// 从 0 开始输入几就输出第几个数的值
		fib = new int[n+1]; // 要想输入n就输出n对应的值,就需要数组设置的长度为n+	1,从0开始
		

		System.out.println(fibonacco(n)); // 调用方法并输出值
		
		
	}
	
	public static int fibonacco(int n) {
		if(n == 1) return 1;
		if(n == 2) return 1;
		return fibonacco(n-1) + fibonacco(n-2);
	}
}

如果数值比较大时,会出现多次重复计算,时间复杂度达到O(2n)。
例如: fib[4] = fib[3] + fib[2] = fib[2] + fib[1] + fib[2] ;
动态规划:自底向上法
时间复杂度:O(n), 空间复杂度O(n)

// 自底向上的方法: 从输入的最小参数值开始,逐步构建更大的参数值的解
public class FeiBoNaQieShuLie2 {
	private static int[] fib;
	
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		int n = input.nextInt();// 从 0 开始输入几就输出第几个数的值
		fib = new int[n+1]; // 要想输入n就输出n对应的值,就需要数组设置的长度为n+	1,从0开始
		
		System.out.println(fib(n)); // 调用方法并输出值
		
		
	}
	
	public static int fib(int n) {
		if(n == 1 ) return 1;
		if (n == 2) return 1;
		// 最后两个是设定好的
		fib[1] = 1;
		fib[2] = 1;
		// 求出第n个的值
		for(int i = 3; i <= n; i++) {
			fib[i] = fib[i-1] + fib[i-2];
		}
		// 返回第n个的值
		return fib[n];
	}
}

动态规划:自顶向下法
时间复杂度:O(n), 空间复杂度O(n)

// 自顶向下:保留递归调用,如果某个子问题的解已经求过,就直接使用这个值,增加备忘录
public class FeiBoNaQieShuLie3 {
	private static int[] fib;
	
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		int n = input.nextInt();// 从 0 开始输入几就输出第几个数的值
		fib = new int[n+1]; // 要想输入n就输出n对应的值,就需要数组设置的长度为n+	1,从0开始
		

		System.out.println(fibonacco(n)); // 调用方法并输出值
		
		
	}
	
	public static int fibonacco(int n) {
		if(n == 1) return 1;
		if(n == 2) return 1;
		if (fib[n] != 0) {
			return fib[n];
		}
		return fib[n] = fibonacco(n-1) + fibonacco(n-2);
	}
}

最强算法:
因为每次只用到了最后两个的值,所以只需要保存最后两个的值即可
时间复杂度O(n), 空间复杂度O(1)

public static int fibonacco(int n) {
		if(n == 1) return 1;
		if(n == 2) return 1;
		int sum = 2, a = 1, b = 1;
		for (int i = 3; i <= n; i++) {
			sum = a + b;
			a = b;
			b = sum;
		}
		return sum;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值