我的笔记之斐波那契数列

青蛙跳台阶:

一只青蛙一次可以跳上一级台阶也可以一次跳上两级的台阶, 现在有一个n级的台阶,问青蛙有多少种跳法?

反向思考:
要想跳上第 n 级台阶,该怎么跳?
答:要么从第 n−1 级台阶跳一级上来,要么从第 n−2 级台阶跳两级上来,再无他法。
因此,令 f(n) 表示从第一级台阶跳上第 n 级台阶有跳法总数。则有如下递推公式:
f(n)=f(n−1)+f(n−2)
这很明显就是斐波那契数列嘛!那么问题就简单了,代码如下:

public int JumpFloor(int n) {
	if (n < 1) {return -1;}
	if (n == 1) {return 1;}
	if (n == 2) {return 2;}
	int result = 0, temp1 = 1, temp2 = 2, count = 0;
	while (count != n - 2) {//因为count==1的时候,result是3级时的结果,以此类推,n级时,count==n-2
		result = temp1 + temp2;
		temp1 = temp2;
		temp2 = result;
		count++;
	}
	return result;
}复制代码

变形青蛙跳台阶:

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。 求该青蛙跳上一个n级的台阶总共有多少种跳法?

同样反过来思考:

跳上第n阶台阶,有多少种跳法?

答:可以从n-1阶跳上来,也可以从n-2阶跳上来,也可以从n-3阶跳上来……可以从第1阶跳上来。则:
f(n)=f(n-1)+f(n-2)+…f(1)
同理:
f(n-1)=f(n-2)+f(n-3)+…f(1)
综上:
f(n)=2f(n−1)=4f(n−2)=8f(n−3)=...
即:
f(n)=2f(n−1)=2^2f(n−2)=2^3f(n−3)=...=2^(n−1)f(n−(n−1))=2^(n−1)f(1)
因为 f(1)=1,所以 f(n)=2^(n-1)

public static int JumpFloorII(int n) {
    int result=1;
    for(int i=1;i<=n-1;i++){
        result=result*2;
    }
    return result;
}复制代码

矩形覆盖问题:

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

若第一个矩形竖着填充,那么问题就变成了求填充2*(n-1)大矩形的方法数

若第一个矩形横着填充,那么它下面的两个格子只能同样横着填充,问题就变成了求填充2*(n-2)大矩形的方法数


若令f(n)表示填充n*2的大矩形则:
f(n)=f(n-1)+f(n-2)
同样这也是一个斐波那契数列,解决代码和第一个问题一样;

斐波那契数列原问题:

解法如下:

// 解法1:算法简洁但效率较低(不推荐)
public int Fibonacci(int n,String mark) {
    if(n<=0){
    return 0;
    }
    if(n==1){
    return 1;
    }
    return Fibonacci(n-1)+Fibonacci(n-2);
}
// 解法2:思路清晰且效率高
public static int Fibonacci(int n) {
	if (n <= 0) {
     return 0;
	}
	if (n == 1) {
     return 1;
	}
	int result = 0, temp1 = 0, temp2 = 1, count = 0;
	while (count != n - 1) {
		result = temp1 + temp2;
		temp1 = temp2;
		temp2 = result;
		count++;
	}
	return result;
}复制代码


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值