算法设计之斐波那契与跳台阶

1. 斐波那契数列

费波那契数列(意大利语:Successione di Fibonacci),又译为费波拿契数、斐波那契数列、费氏数列。
在数学上,费波那契数列是以递归的方法来定义:

当n趋近于无穷大时,后一项与前一项的比值趋近于1.618,因此也叫黄金比例数列。

斐波那契写书时以兔子繁殖问题为例子,因此也叫兔子繁殖数列。

2.斐波那契Java实现

package atOffer_09;

import java.util.Scanner;

public class Fibonacci {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		System.out.println(fibonacci(num));
		sc.close();

	}
	
	private static int fibonacci(int num) {
		int[] result = new int[] {0,1};
		if(num < 2)
			return result[num];
		int fibonacciMinus2 = result[0];
		int fibonacciMinus1 = result[1];
		int fibonacciNum = 1;
		
		for(int i = 2; i <= num; i++) {
			fibonacciNum = fibonacciMinus1 + fibonacciMinus2;
			fibonacciMinus2 = fibonacciMinus1;
			fibonacciMinus1 = fibonacciNum;
		}
		
		return fibonacciNum;
	}

}

确认前两项线性实现,效率比递归快

3.跳台阶问题

问题描述:一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。

设f(n)表示青蛙跳上n级台阶的跳法数。当只有一个台阶时,
即n = 1时, 只有1种跳法;
当n = 2时,有两种跳法;
当n = 3 时,有3种跳法;
当n很大时,青蛙在最后一步跳到第n级台阶时,有两种情况:
一种是青蛙在第n-1个台阶跳一个台阶,那么青蛙完成前面n-1个台阶,就有f(n-1)种跳法,这是一个子问题。
另一种是青蛙在第n-2个台阶跳两个台阶到第n个台阶,那么青蛙完成前面n-2个台阶,就有f(n-2)种情况,这又是另外一个子问题。所以这种问题实质上就是斐波那契数列问题,用公式表达为:

用代码实现和斐波那契相同:

package atOffer_09;

import java.util.Scanner;

public class JumpFloor {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		System.out .println(JumpSteps(num));
		sc.close();
	}
	
	private static int JumpSteps(int num) {
		int[] jump = new int[] {0,1};
		if(num < 2) {
			return jump[num];
		}
		
		int jumpMinus1 = jump[1];
		int jumpMinus2 = jump[0];
		int jumpStep = 1;
		
		for(int i = 2; i <= num; i++) {
			jumpStep = jumpMinus1 + jumpMinus2;
			jumpMinus2 = jumpMinus1;
			jumpMinus1 = jumpStep;
		}
		
		return jumpStep;
	}

}

4.问题变型

变态跳台阶指一只青蛙可以一次跳任意阶台阶,求问跳n阶台阶的方法,解决方法思想也可以规划为写公式让斐波那契求解的过程,跳n阶的时候即f(n) = f(n-1)+f(n-2)+...+f(2)+f(1)+1=2^(n-1)种方法

兔子繁殖问题是斐波那契经典问题解决方法同理。

矩形覆盖问题:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
 请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?同理

参考文献:

【1】https://blog.csdn.net/K346K346/article/details/52576680

【2】https://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97#%E5%92%8C%E9%BB%83%E9%87%91%E5%88%86%E5%89%B2%E7%9A%84%E9%97%9C%E4%BF%82

猜你喜欢

转载自blog.csdn.net/wannuoge4766/article/details/83957311