一道简单算法题的思考(青蛙跳台阶问题)

题目:

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

 

以下是思考时间

𓃟𓃠𓃥𓃩𓃬𓃭𓃮𓃯𓃰𓃱𓃲𓃵𓃶𓄇𓄿𓅀𓅂𓅃𓅘𓅙𓅚𓅛𓅜𓅝𓅞𓅟𓅠𓅡𓅢𓅣𓅤𓅥𓅦𓅧𓅨𓅩𓅪𓅫𓅬𓅭𓅮𓅯𓅰𓅱𓅲𓅳𓅷𓅺𓅼𓅽𓆈𓆉𓆊𓆏𓆐𓆙𓆚𓆣𓆤𓆦

		                   _ooOoo_
		                  o8888888o
		                  88" . "88
		                  (| -_- |)
		                  O\  =  /O
		               ____/`---'\____
		             .'  \\|     |//  `.
		            /  \\|||  :  |||//  \
		           /  _||||| -:- |||||-  \
		           |   | \\\  -  /// |   |
		           | \_|  ''\---/''  |   |
		           \  .-\__  `-`  ___/-. /
		         ___`. .'  /--.--\  `. . __
		      ."" '<  `.___\_<|>_/___.'  >'"".
		     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
		     \  \ `-.   \_ __\ /__ _/   .-` /  /
		======`-.____`-.___\_____/___.-`____.-'======
		                   `=---='
		^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
			         佛祖保佑       永无BUG



  ┏┓   ┏┓
┏┛┻━━━┛┻┓
┃       ┃  
┃   ━   ┃
┃ ┳┛ ┗┳ ┃
┃       ┃
┃   ┻   ┃
┃       ┃
┗━┓   ┏━┛
    ┃   ┃   神兽保佑        
    ┃   ┃   代码无BUG!
    ┃   ┗━━━┓
    ┃       ┣┓
    ┃       ┏┛
    ┗┓┓┏━┳┓┏┛
      ┃┫┫  ┃┫┫
      ┗┻┛  ┗┻┛

𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀻𓀼

以上是思考时间

 

 

 

思考【0】:

首先大家能想到的肯定是递归算法,

只需要抽象出青蛙在跳第n阶台阶的时候需要由上一次状态跳1阶或者是跳2阶来到达,

所以:第n阶台阶的跳法 = 第n-1次台阶跳法 + 第n-2次台阶的跳法

 

简单递归(80%):

    public int climbStairs(int n) {
        if (n == 0 || n == 1 || n == 2) return n;
        return climbStairs(n - 1) + climbStairs(n - 2);
    }

时间复杂度:O(2^n)
空间复杂度:递归栈的空间

 

 

思考【1】:

简单的递归算法,存在一个重复计算的问题,具体如下图举例:

 

 

优化:加数组缓存,减少不必要的递归

优化的递归(50%)

    public int climbStairs(int n) {
        int memo[] = new int[n];
        return climb_Stairs(0, n, memo);
    }

    public int climb_Stairs(int i, int n, int memo[]) {
        if (i > n) {
            return 0;
        }
        if (i == n) {
            return 1;
        }
        if (memo[i] > 0) {
            return memo[i];
        }
        memo[i] = climb_Stairs(i + 1, n, memo) + climb_Stairs(i + 2, n, memo);
        return memo[i];
    }

时间复杂度:O(n) 没有重复的计算
空间复杂度:O(n) 和递归栈的空间

 

 

思考【2】:

回顾一下四大算法思想:

穷举法(暴力法)

分治法

动态规划

贪心算法

问题其实可以抽象成一个斐波那契数列,即第1个为1,第二个为2,从第三个开始等于前两个数之和

 

动态规划(30%):

    public int climbStairs(int n) {
        if (n == 1) return 1;
        int[] dp = new int[n];
        dp[0] = 1;
        dp[1] = 2;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n-1];
    }

时间复杂度:O(n)
空间复杂度:O(n)

 

思考【3】:

当我们算第n个台阶的时候,存在空间浪费的情况,数组可能是不需要的

 

优化的动态规划(10%):

    public int climbStairs(int n) {
        if (n == 0 || n == 1) return n;
        int a = 1, b = 1, c = 0;
        for (int i = 2; i <= n; ++i) {
            c = a + b;
            a = b;
            b = c;
        }
        return c;
    }

时间复杂度:O(n)
空间复杂度:O(1)

 

 

思考【4】:

进阶变种题,变态跳台阶:

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

 

方法也有很多种,这里提供一种最简单的动态规划算法,n的阶乘

一行代码搞定:

	public int climbStairs(int n) {
			return n <= 0 ? 0 : 1 << (n - 1);
	}

时间复杂度:O(n)

空间复杂度:O(1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值