题目描述
个人思路分析:
青蛙只能选择跳一个台阶和跳俩个台阶,正着看比较复杂,我之前正着看用了俩层循环穷举排列解题,很多小错误。
接着通过画图找到了方法,我们可以从最后一步看起,到达最后一步可以在n-1和n-2的位置,例如n=4的话,就有3和2俩种情况,在往下画图,就会发现这是一种叠加式的树形图,我们把最下面的1当做f1,把0当做f2,那么2的值就是f1+f2,如果再以2的这一层为底的话,那么2左边的1就变成了f2的位置,所以把f1的值赋给f2。 然后就是不断迭代循环,以target为终点就可以了。(注意:其实这一题和下面一题原理一样,具体的方法也是多变的)
1 public class Solution { 2 public int JumpFloor(int target) { 3 if(target<2) 4 return target; 5 int f1=1; 6 int f2=0; 7 int f=0; 8 for(int i=1;i<=target;++i) 9 { 10 f=f1+f2; 11 f2=f1; 12 f1=f; 13 } 14 return f; 15 } 16 }
题目描述
这一题我也是画图找规律的,我发现从2开始之后,它的所有求解数量都会和它的前一个数有关系,例如,3的求解数量为4,而4的求解数量是3的数量和加上3之前的数量和(也就是3的数量和),即是3的2倍,而对于5的数量它也是4的2倍。
1 public class Solution { 2 public int JumpFloorII(int target) { 3 if (target <=2) { 4 return target; 5 6 } 7 8 int f1 = 1; 9 int f0 = 1; 10 11 int fNow = 0; 12 int fPre = 0; 13 if (target > 2) { 14 15 fPre = f1 + f0; 16 fNow = (int) Math.pow(fPre, (target - 1)); 17 18 } 19 return fNow; 20 21 } 22 23 24 }
不过对于这题来说,也可以利用公式来求解(下面这个更为严谨,对于相似题目扩展也更有启发):
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-1)-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) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:
| 1 ,(n=0 )
f(n) = | 1 ,(n=1 )
1 public class Solution { 2 public int JumpFloorII(int target) { 3 if (target <= 0) { 4 return -1; 5 } else if (target == 1) { 6 return 1; 7 } else { 8 return 2 * JumpFloorII(target - 1); 9 } 10 } 11 }