剑指offer--变态跳台阶

版权声明:本文为博主原创文章,评论区告知一声,大家随意转载! https://blog.csdn.net/MessageBox_/article/details/84671735

题目如下:

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

解题思路:
其实有两种解题思路,个人更倾向于第二种方法,应为个人觉得它更符合计算机解决问题的思路。

在这道题目之前,其实还有一个简单的青蛙跳台阶,就是青蛙可以跳一次和跳两次,这个其实很简单也没啥好说的,使用递归就可以得到我们想要的结果。
我们看看这道题,我一开始的想法也是使用递归,最后发现其实还是那么回事。。。

思路一:

假设  青蛙跳到n级的方法是 F(n)
那么F(n)是怎么来的呢?我们从后往前思考
	 1.青蛙跳到第n-1级,最后跳1步 ,而跳到n-1级的跳法是F(n-1)   A1 =  F(n-1)
	 2.青蛙跳到第n-2级,最后跳2步 ,而跳到n-2级的跳法是F(n-2)   A2 =  F(n-2)
		.....
	 n-1.青蛙跳到第1级,最后跳n-1步 ,而跳到1级的跳法是F(1)   An-1 =  F(1)
	 n. 青蛙直接跳n级,An =  1

那么我么可以得到如下结果:
a. F(n) = A1 + A2 + …+ An-1 + An = F(n-1) + F(n-2) + … + F(1) + 1
b. F(n-1) = F(n-2) + … + F(1) + 1
c. F(n) = F(n-1) + F(n-1) = 2F(n-1)

所以结果就很简单了

function jumpFloorII(number)
{
    if( number === 1){
        return 1;
    }else{
        return  2 * jumpFloorII(number  - 1);
    }
}

所以这道题究竟是算法呢还是数学呢?。。。。

思路二:
这个方法是我查看其他解法时发现的,本质和思路一差不多,不同的地方在于它并没有上文中的推理步骤b和c,仅仅是依靠公式a就得到的最终的结果,下面让我们一起看看代码

	function jumpFloorII(number)
	{
	    if(number === 1){
	        return 1;        
	    }else if( number > 1){
	        //创建一个空数组,用来保存对应每一个小于number的n的跳法结果        
	        let arr = new Array(number + 1).fill(0);        
	        arr[0] = 0;
	        arr[1] = 1;
	        for(let i = 2; i <= number; i++ ){
	            // An = An-1 + An-2 + ... + A1 + 1
	            for( let j = 1 ; j < i ; j++  ){
	                arr[i] += arr[j];
	            }
	            arr[i] += 1;
	        }
	        return arr[number];
	    }else{
	        return -1;
	    }
	}

巧妙的使用数组,将每一次的An-1计算结果保存起来,而后面的An的计算结果是依赖前面的A1…An-1的。

猜你喜欢

转载自blog.csdn.net/MessageBox_/article/details/84671735