这是悦乐书的第159次更新,第161篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第18题(顺位题号是70)。你正在爬楼梯,它需要n步才能达到顶峰。每次你可以爬1或2步,你可以通过多少不同的方式登顶?注意:给定n是一个正整数。例如:

输入:2

输出:2

说明:有两种方法可以爬到顶端

1、1步 + 1步

2、2步

输入:3

输出:3

说明:有三种方法可以爬到顶端

1、1步 + 1步 + 1步

2、1步 + 2步

3、2步 + 1步

输入:4

输出:5

说明:有5种方法可以爬到顶端

1、1步 + 1步 + 1步 + 1步

2、1步 + 1步 + 2步

3、1步 + 2步 + 1步

4、2步 + 1步 + 1步

5、2步 + 2步

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

关于题目,可以从简单的条件开始推导。

当n等于1的时候,有1种方式。

当n等于2的时候,有2种方式。

当n等于3的时候,有3种方式。

当n等于4的时候,有5种方式。

当n等于5的时候,有8种方式。

看到这,你会发现从n等于2开始,后一项等于前两项的和,这时很容易想到递归,于是就有了第一种解法。

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

03 第二种解法

上面的解法,你应该也发现问题了,运行太慢了。有什么可以优化的呢?既然只是求前两个数的和,那么可以引用数组来存值,而不是每次都来重新算一次。

public int climbStairs2(int n) {
int[] arr = new int[n+1];
return climb(n, arr);
} public int climb(int n, int[] arr){
if (n == 0 || n == 1) {
return 1;
} else if(arr[n] > 0) {
return arr[n];
}
arr[n] = climb(n-1, arr) + climb(n-2, arr);
return arr[n];
}

在climb方法里判断里,是要加上else if那个判断的,目的是避免重复计算,不判断的话就和第一种差不多了。

04 第三种解法

既然利用数组来存值,那么是不是可以省掉递归?直接拿数组元素返回结果就行。

public int climbStairs3(int n) {
int[] arr = new int[n+1];
arr[0] = 1;
arr[1] = 1;
for (int i=2; i<arr.length; i++) {
arr[i] = arr[i-1]+arr[i-2];
}
return arr[n];
}

05 三种解法对比

为了验证哪种解法花费的时间更少,编写了一些简易的测试代码。

public static void main(String[] args) {
Easy_070_ClimbingStairs instance = new Easy_070_ClimbingStairs();
int arg = 44;
long start = System.nanoTime();
int result = instance.climbStairs(arg);
long end = System.nanoTime();
System.out.println("climbStairs---输入:"+arg+" , 输出:"+result+" , 用时:"+(end-start)/1000+"微秒");
System.out.println("----------------------------");
long start2 = System.nanoTime();
int result2 = instance.climbStairs2(arg);
long end2 = System.nanoTime();
System.out.println("climbStairs2---输入:"+arg+" , 输出:"+result2+" , 用时:"+(end2-start2)/1000+"微秒");
System.out.println("----------------------------");
long start3 = System.nanoTime();
int result3 = instance.climbStairs3(arg);
long end3 = System.nanoTime();
System.out.println("climbStairs3---输入:"+arg+" , 输出:"+result3+" , 用时:"+(end3-start3)/1000+"微秒");
}

下面是运行的结果

climbStairs---输入:44 , 输出:1134903170 , 用时:2795896微秒
----------------------------
climbStairs2---输入:44 , 输出:1134903170 , 用时:9微秒
----------------------------
climbStairs3---输入:44 , 输出:1134903170 , 用时:6微秒

可以看出来,第三种解法是最优的,递归是好算法,但是会造成很多重复计算,影响速度,需要分场景来使用递归算法。

06 小结

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

LeetCode算法题-Climbing Stairs(Java实现)的更多相关文章

  1. LeetCode算法题-Heaters(Java实现)

    这是悦乐书的第239次更新,第252篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第106题(顺位题号是475).冬天来了!您在比赛期间的第一份工作是设计一个固定温暖半径 ...

  2. LeetCode算法题-Sqrt(Java实现)

    这是悦乐书的第158次更新,第160篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第17题(顺位题号是69). 计算并返回x的平方根,其中x保证为非负整数. 由于返回类型 ...

  3. LeetCode算法题-Min Cost Climbing Stairs(Java实现)

    这是悦乐书的第307次更新,第327篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第176题(顺位题号是746).在楼梯上,第i步有一些非负成本成本[i]分配(0索引). ...

  4. LeetCode算法题-Subdomain Visit Count(Java实现)

    这是悦乐书的第320次更新,第341篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第189题(顺位题号是811).像"discuss.leetcode.com& ...

  5. LeetCode算法题-Number of Lines To Write String(Java实现)

    这是悦乐书的第319次更新,第340篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第188题(顺位题号是806).我们要将给定字符串S的字母从左到右写成行.每行最大宽度为 ...

  6. LeetCode算法题-Unique Morse Code Words(Java实现)

    这是悦乐书的第318次更新,第339篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第186题(顺位题号是804).国际莫尔斯电码定义了一种标准编码,其中每个字母映射到一系 ...

  7. LeetCode算法题-Rotate String(Java实现)

    这是悦乐书的第317次更新,第338篇原创 在开始今天的算法题前,说几句,今天是世界读书日,推荐两本书给大家,<终身成长>和<禅与摩托车维修艺术>,值得好好阅读和反复阅读. 0 ...

  8. LeetCode算法题-Rotated Digits(Java实现)

    这是悦乐书的第316次更新,第337篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第185题(顺位题号是788).如果一个数字经过180度旋转后,变成了一个与原数字不同的 ...

  9. LeetCode算法题-Letter Case Permutation(Java实现)

    这是悦乐书的第315次更新,第336篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第184题(顺位题号是784).给定一个字符串S,将每个字母单独转换为小写或大写以创建另 ...

随机推荐

  1. 华为路由器帧中继 FR 实验

    帧中继简介 帧中继( Frame Relay)是一种用于连接计算机系统的面向分组的通信方法.它主要用在公共或专用网上的局域网互联以及广域网连接.大多数公共电信局都提供帧中继服务,把它作为建立高性能的虚 ...

  2. QT 实现图片旋转的两种方法

    第一种方案 使用 QPixmap 的 transformed 函数来实现旋转,这个函数默认是以图片中心为旋转点,不能设置旋转的中心点,使用如下: QMatrix matrix; matrix.rota ...

  3. 关于VUE首屏加载过长的优化,VUE项目开发优化

    1. 按需引入UI组件 当下市面上流行的UI组件基本都支持按需加载,本文以Element UI为例: (1)     新建一个elementUI.js文件 (2)     访问地址找到按需引入方式的说 ...

  4. 南大算法设计与分析课程复习笔记(2)L2 - Asymptotics

    一.几种比较复杂度的符号 数据结构有描述,相关严格数学定义也不想说了,就这么过了吧. 二.最大子数组的几种解决方法 从最复杂的暴力解法过渡到最简单的动态规划 解析和代码见这里:http://www.c ...

  5. [转]RPA简介

    本文转自:https://www.cnblogs.com/wendyzheng/articles/9211530.html 开篇: 公司正在全面推广RPA,正好借此机会学习一下,发现国内对RPA的了解 ...

  6. .NET 配置文件实用指南

    我想大家对配置文件一定不会陌生,在大部分的项目中都会用到它,在此笔者给出一些配置文件的实用示例. XML配置文件 利用XML格式的配置文件储存连接字符串,再用反射技术读取. using System. ...

  7. 分页Sql语句

    第一种 Top剔除法.去除Top (pageIndex-1)*PageSize * FROM dbo.SBD_EXCHANGE_BILL ) EB_ID FROM dbo.SBD_EXCHANGE_B ...

  8. UWP: 妙用自定义 Action 以简化并重用代码

    相信每一位 App 开发者,在开发过程中,都会有一些代码被反复用到,比如:复制文本,打电话,发短信,发邮件,给应用添加评论等等.在项目之间复制这些代码段,实在不是一个好办法,所以大家可能会把这些代码放 ...

  9. PHP定界符eof 的使用

    PHP是一个Web编程语言,在编程过程中难免会遇到用echo来输出大段的html和javascript脚本的情况,如果用传统的输出方法 ——按字符串输出的话, 肯定要有大量的转义符来对字符串中的引号等 ...

  10. 18.QT-QPlainEdit 信号与槽

    QPlainEdit编辑功能 Public Slots void appendHtml ( const QString & html ) void appendPlainText ( cons ...