:-: 9.1 爬楼梯

* * * * *

**题干:**

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

~~~

输入: 2

输出: 2

解释: 有两种方法可以爬到楼顶。

1. 1 阶 + 1 阶

2. 2 阶

~~~

示例 2:

~~~

输入: 3

输出: 3

解释: 有三种方法可以爬到楼顶。

1. 1 阶 + 1 阶 + 1 阶

2. 1 阶 + 2 阶

3. 2 阶 + 1 阶

~~~

**题目分析:**

如果放在中学课堂之上,这就是一个典型的排列组合问题,所以我们可以采用排列组合的方式来解决这个问题,但是这个方法处理次数在随着n的增加,急剧增长,虽然现在我们的电脑处理速度快,但是我们也不应该这样伤害它呀!我们再来分析一下,当n = 1的时候,f(1) = 1;当n = 2的时候,f(2) = 2;当n = 3的时候,f(3) = 3;当n = 4的时候,f(4) = 5,我们发现f(n) = f(n - 1) + f(n - 2)。这个时候我们可以发现这不就是个斐波那契数列吗?我们可以采用递归的方式来做呀,再看斐波那契数列函数,也是动态规划方程呀。

**新手有可能遇到的解题思路陷阱:**

就是上文所提到的排列组合方法,此方法属于暴力枚举,时间复杂度是值数级。坚决不推荐此方法(并不是其他的算法题用排列组合就不好,单指此题)。

**解题思路分析以及代码实现:**

第一种思路:排列组合(不推荐),方法中使用long类型,是因为当n = 14以后,nums函数会出现int范围越界,所以采用了long类型。

第一种思路代码:

~~~

public long climbStairs(int n) {

if (n <= 0) {

return (long) 0;

} else {

long sum = 0;

int two = n / 2;// 计算2的个数

int one = n % 2;// 计算当2最多是1的个数

for (long i = two; i >= 0; i--) {

// 减1个2增加两个1

sum += nums(one + 2 * (two - i), i);

}

return sum;

}

}

public static long nums(long one, long two) {

// x1是1的个数,x2是2的个数

long down = 1;

long up = 1;

for (int i = 1; i <= one; i++) {

down *= i;

}

for (long i = one + two; i > two; i--) {

up *= i;

}

return up / down;

}

~~~

**复杂度分析**

时间复杂度:O(n^2)。

空间复杂度:O(1)。

第二种思路:递归,我们要是想上n这个台阶,我们要么是在n - 1这个台阶上,要么是在n - 2这个台阶上,然后问题就变为我们怎么到n - 1或n - 2这个台阶上,直至我们分析到n = 1或n = 2时,我们会发现f(n) = f(n - 1) + f(n - 2),由此可写递归算法。

第二种思路代码:

~~~

public int climbStairs(int n) {

if (n < 1)

return 0;

if (n == 1)

return 1;

if (n == 2)

return 2;

return climbStairs(n - 1) + climbStairs(n - 2);

//另一种实现方式

/*return (n == 1 || n == 2) ? n : climbStairs(n - 2) + climbStairs(n - 1);*/

}

~~~

**复杂度分析**

时间复杂度:O(2^n)。

第三种思路:递归+备忘录,但是我们再分析下上面这个递归算法,f(n) = f(n - 1) + f(n - 2),f(n - 1) = f(n - 2) + f(n - 3),f(n - 2) = f(n - 3) + f(n - 4),我们发现什么特别的东西有,我们发现他进行了大量的重复计算,这怎么可以呢?

:-: ![](https://box.kancloud.cn/589c5e4c4618da3e4ccf9a1062175edf_640x352.png)

我们要避免这种无用功,我们可以这样做,利用缓存的思想,把值都存起来,等需要用的时候,直接拿来用,不去进行耗时耗力的计算了

第三种思路代码:

~~~

public int climbStairs(int n) {

Map map = new HashMap();

//List集合也可以,但是要标好位置。

if (n < 1)

return 0;

if (n == 1)

return 1;

if (n == 2)

return 2;

if (map.containsKey(n)) {

return map.get(n);

}

int sum = climbStairs(n - 1) + climbStairs(n - 2);

map.put(n, sum);

return sum;

}

~~~

**复杂度分析**

时间复杂度:O(n)。

空间复杂度:O(n)。

第四种思路:动态规划算法,不使用递归方式,我们将思路逆转过来,自下而上的推理,我们由以上分析发现当n = 1的时候,f(1) = 1;当n = 2的时候,f(2) = 2;当n = 3的时候,f(3) = 3;当n = 4的时候,f(4) = 5,我们发现f(n) = f(n - 1) + f(n - 2),我们所求的当前台阶只和它后后两个台阶发生关系。

第四种思路代码:

~~~

public int climbStairs(int n) {

if (n < 1)

return 0;

if (n == 1)

return 1;

if (n == 2)

return 2;

int sum[] = new int[n];

sum[0] = 1;

sum[1] = 2;

for (int i = 2; i < n; i++) {

sum[i] = sum[i - 1] + sum[i - 2];

}

return sum[n - 1];

}

~~~

**复杂度分析**

时间复杂度:O(n)。

空间复杂度:O(n)。

第五种思路:迭代法(状态压缩法,滚动数组法、滑动窗口法等),还是和第四种一样的思想,我们所求的当前台阶只和它后后两个台阶发生关系,只要保证我们现在所求的当前台阶后的两个台阶就可以了。同时也是优化空间复杂度。

第五种思路代码:

~~~

public int bestStairs(int n) {

if (n < 1)

return 0;

if (n == 1)

return 1;

if (n == 2)

return 2;

int sum = 0, sum1, sum2;

sum1 = 1;

sum2 = 2;

for (int i = 2; i < n; i++) {

sum = sum1 + sum2;

sum1 = sum2;

sum2 = sum;

}

return sum;

}

~~~

**复杂度分析**

时间复杂度:O(n)。

空间复杂度:O(1)。

**若有理解错误的、写错的地方、更好的思路,方法,望各位读者评论或者发邮件指正或指点我,不胜感激。**

java 爬楼梯算法_9.1 爬楼梯相关推荐

  1. java 爬楼梯算法_动态规划-爬楼梯问题java实现

    最近开始看算法导论,研究了一下动态规划,下面就开始直入主题开始记录近期看的第一个知识点动态规划.提起动态规划就不得不提几个动态规划的金典问题爬楼梯.国王金矿.背包问题.今天就仔细分析一下爬楼梯问题. ...

  2. 斐波那契数列-爬楼梯算法

    爬楼梯算法 有n级楼梯,有2种爬法,1次1级,或1次2级,问,n级楼梯有多少种爬法? 递归求解 首先,当只有一阶楼梯的时候,很显然只有一种走法:有两阶楼梯的时候,也很显然的知道有两种走法.就会有下面这 ...

  3. python爬楼梯问题_爬楼梯算法的数学思路

    爬楼梯算法的数学思路 今日腾讯实习面试,问到一题算法. 爬楼梯问题:一个楼梯一共n个台阶,一次上1或者2个台阶.问,一共多少种解法. 这个问题,当时学递归的时候,我记得做过.但是已经一年半没写过递归和 ...

  4. 爬楼梯算法 一个小孩练习爬台阶,一共10级台阶,小孩可以一次向上选择爬1-3级

    爬楼梯算法 一个小孩练习爬台阶,一共10级台阶,小孩可以一次向上选择爬1-3级.但是第3级和第6级台阶被施加了魔法,小孩一旦踏上就会停下来就开始跳<新宝岛>.那么,不让小孩跳<新宝岛 ...

  5. python爬楼梯_Python3爬楼梯算法示例

    Python3爬楼梯算法示例 本文实例讲述了Python3爬楼梯算法.分享给大家供大家参考,具体如下: 假设你正在爬楼梯.需要 n 步你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同 ...

  6. 一步一步写算法(之爬楼梯)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两天上网的时候看到一个特别有意思的题目,在这里和朋友们分享一下: 有一个人准备开始爬楼梯,假 ...

  7. 挑战杯刷题-上楼梯算法

    问题描述与算法如下 /*** 小白上楼梯*/import java.util.Scanner;public class _02_5小白上楼梯 {public static void main(Stri ...

  8. Java爬虫技术(一)普通网站爬取图片

    爬虫简单介绍 用户和网站服务器的操作如下 而爬虫需要做的是模拟仿照用户机,去向服务器发送请求数据,并接受响应数据,接着去解析数据,获得我们想要的数据 步骤大致分为 准备好要爬取的网址 定义爬虫的参数 ...

  9. Java爬虫历险记 -- (1)爬取百度首页的logo

    Java爬虫历险记 – (1)爬取百度首页的logo 在这篇文章里,介绍两种方式来获取百度网页的logo: (1)Httpclient (2) jsoup + Httpclient ,详细的运行结果可 ...

  10. 【用Java爬取网页图片——爬虫爬取数据】

    用Java爬取网页图片--爬虫爬取数据 1.在创建项目中导入jsoup 2.创建一个保存下载图片的路径 3.使用URL读取网页路径,jsoup读取网页内容 4.利用属性标签获取图片连接块 5.因为该路 ...

最新文章

  1. C#使用ICSharpCode.SharpZipLib.dll压缩文件夹和文件
  2. 百度发布智能电视伴侣,并公布短视频计划
  3. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)解题报告
  4. java48关键_Java48个关键字速查表
  5. 小程序开发入门教程 一
  6. Tomcat性能调优方案
  7. *为需要读写VRML(.wrl)文件的同志们指点一条路
  8. kinect 2.0 SDK-深度图与彩色图对齐
  9. UnityWebPlayer缓存清理工具
  10. 虚拟光驱安装服务器无法运行,Win7新装虚拟光驱无法打开的解决方法
  11. HP服务器远程管理工具iLO详细介绍
  12. Iphone快捷指令示例:自动更换墙纸并叠放近期日程在墙纸上
  13. C语言练习——基础篇
  14. win10启动项_win10系统开机启动项的设置教程
  15. f.read()函数详解
  16. DataWhale活动-二手车价格预测 task3
  17. 《互联网时代》第二集·浪潮
  18. 批量抠图,只需要这几行python代码!
  19. nodejs+vue+elementui休闲娱乐美食优惠卷商城销售系统
  20. 切片 (python)

热门文章

  1. C++复数运算符重载,复数开平方
  2. 三年探索:一条自控、电信/科类学生的技术成长路线
  3. Linux截图gif,Ubuntu下截图与录制视频并作成gif图片
  4. 软路由防火墙IPcop的安装,配置
  5. Git 常用术语 WIP PTAL CC LGTM 解释
  6. 10.24程序员节专辑——程序员最爱的数字,1024的秘密
  7. python爬虫02 - 爬虫请求模块 request库 json数据
  8. 阿里云ACP认证考试笔记
  9. hdu1197(十进制十六进制十二进制位数和)
  10. 【安全热点】阿里巴巴月饼门,观点两极化,孰对孰错?