题1:跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
示例1
输入
1
返回值
1
示例2
输入
4
返回值
5
解析:
-
规律总结:
台阶 : 跳法 0 0 1 1 2 2 (1,2) 3 3 (111,12,21) 4 5 (1111,112,22,211,121) 5 8 (11111,1112,122,212,221,2111,1211,1121) ... 咋看上去这么眼熟呢...
-
理论推导:
仔细审题发现青蛙只能有两种跳台阶的方式,要么跳1级,要么跳2级。
-
假设青蛙已经登上N级的台阶,那么它有两种情况
- 最后一步为n-1级台阶
- 此时跳法为f(n-1)
- 最后一步为n-2级台阶
- 此时跳法为f(n-2)
- 最后一步为n-1级台阶
-
综上可以得出总跳法为:
f(n) = f(n-1) + f(n-2)
且跳一阶的时候 f(1) = 1 ,跳两阶的时候可以有 f(2) = 2
-
最终得到一个
斐波那契数列
|—— 1, (n=1) | f(n) =|—— 2, (n=2) | |—— f(n-1)+f(n-2) ,(n>2,n为整数)
-
解答:
-
经典递归算法:
public int JumpFloor(int target) { if((target==0)||(target==1)||(target==2)){ return target; } int sum=0; if(target>2){ sum+=JumpFloor(target-1)+JumpFloor(target-2); } return sum; }
但是时间复杂度有点大,重复计算值过多,需优化:
重温经典:
剑指offer打卡day04:平衡二叉树&斐波那契数列中对Fibonacci递归的优化
-
优化(用数组对值进行储存):
public int JumpFloor(int target) { int Fib_array[] = new int[target+1]; //因为Fib_array[2] == 2,需要将首位改成1才符合题意 Fib_array[0] = 1; Fib_array[1] = 1; for(int i=2;i<=target;i++){ Fib_array[i] = Fib_array[i-1] + Fib_array[i-2]; } return Fib_array[target]; }