题目分析
问题本质:斐波那契数列
令跳法为f(n),
如果n=1:{{1}},f(1)=1;
如果n=2:{{1,1},{2}},f(2)=2;
如果n=3,{{1,1,1},{1,2},{2,1}},f(3)=3;
如果n=6,有两种情况:1)目前在5阶,跳1步到6;2)目前在4阶,跳2步到6。即f(6)=f(5)+f(4);
... ...
如果有n阶(n>2),1)目前在n-1阶,跳1步到n;2)目前在n-2阶,跳2步到n。即f(n)=f(n-1)+f(n-2)。
根据规律,最简单的方式就是递归:
public class Solution {
public int JumpFloor(int target) {
if(1==target){return 1;}
if(2==target){return 2;}
return JumpFloor(target-1)+JumpFloor(target-2);
}
}
考虑时间效率:尽量不用递归,可以顺着规律实现
public class Solution { public int JumpFloor(int target) { if(target<3){return target;} int first = 1,second = 2,third = 0; for(int i=0;i<target;i++){ third = first + second; first = second; second = third; } return third; } }
若一次可以跳n次,即可以一步跳到目的地。
分析如下:
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
...
f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)
说明:
1) 这里的f(n) 代表的是n个台阶有一次1,2,...n阶的跳法数。
2) n = 1时,只有1种跳法,f(1) = 1
3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,
那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:
f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)
6) 由以上结论,继续简化:
因为f(n-1) => f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
所以f(n) = { f(0) + f(1) + f(2) + f(3) + ... + f(n-2) }+ f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
7) 得出最终结论,总得跳法为:
| 1 ,(n=0 )
f(n) = | 1 ,(n=1 )
public class Solution {
public int JumpFloorII(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else {
return 2 * JumpFloorII(target - 1);
}
}
}
非递归:
public class Solution {
public int JumpFloorII(int target) {
if(1 == target)return 1;
int num = 1,result = 0;
for(int i = 2;i <= target;i++){
result = 2*num;
num = result;
}
return result;
}
}