青蛙跳台阶:
一只青蛙一次可以跳上一级台阶也可以一次跳上两级的台阶, 现在有一个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;
}复制代码