算法_爬楼梯
时间:2022-07-28
本文章向大家介绍算法_爬楼梯,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
爬楼梯
难度:简单
描述:
假设你正在爬楼梯,需要 n 步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?
样例:
比如 n=3,1+1+1=1+2=2+1=3,共有 3 种不同的方法
返回 3
思路分析:
这类题我们首先要来找其中的规律,找到了里面的规律,剩下的就好办了。
我再列举出几个结果:
0 =0 0种方法
1 = 1 种方法
2 = 1+1 =2 2种方法
3=1+1+1=1+2=2+1 3种方法
4 = 1*4 = 1+2+1 = 1+1+2 = 2+1+1 = 2+2 5种方法
5 = 1*5 = 2+1+2 =2+2+1 = 1+2+2 =1+2+1+1 = 1+1+2+1 = 2+1+1+1 = 1+1+1+2 8种方法
想一下他们的规律,试着自己做出来。
代码模板:
/**
* @param n: An integer
* @return: An integer
*/
const climbStairs = function(n) {};
想一想再看答案
想一想再看答案
想一想再看答案
规律:
这道题的规律实际上跟之前做的查找斐波纳契数列中第 N 个数中的规律有点类似。
:::tip 斐波纳契数列中第 N 个数的规律 前 2 个数是 0 和 1,第 i 个数是第 i-1 个数和第 i-2 个数的和。 :::
本题中的规律是:
除了 1 阶楼梯和 2 阶楼梯是一种和两种方法之外,第 n 阶的楼梯的方法是第 i-1 阶楼梯和第 i-2 阶楼梯所用方法的和。
代码:
解题的核心就是逐步推导,推导出n前面的两个值。
- 数组:
const climbStairs = function(n) {
let dp = [0, 1, 2]; // 初始数组 前面三个没有规律
for (let i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]; // 从3开始都是可以由前面两个元素相加推导出来
}
return dp[n];
};
console.log(climbStairs(3), climbStairs(4), climbStairs(5));
- 递归:
const climbStairs = function(n) {
function item(n) {
// 循环退出条件
if (n === 1) return 1;
if (n === 2) return 2;
return item(n - 1) + item(n - 2); // 将递归到1个楼梯和两个楼梯 最后反推到n个楼梯
}
return item(n);
};
console.log(climbStairs(3), climbStairs(4), climbStairs(5));
- 交换变量:
实际上我们只需要 n 之前的两个值,就可以求出 n 所用的方法,所以我们没必要将 n 之前的所有值都推导出来。
所以我们只需要保存这两个值,然后再求出第三个值就可以了。
const climbStairs = function(n) {
// 前两个值的返回结果
if (n === 1) return 1;
if (n === 2) return 2;
let a = 1, // 1阶楼梯
b = 2, // 2阶楼梯
c;
for (let i = 3; i <= n; i++) {
c = a + b; // n的结果
// 为了后续推导,不断保存前两个值
a = b;
b = c;
}
return c;
};
console.log(climbStairs(3), climbStairs(4), climbStairs(5));
实际上,我们也可以使用 ES6 的交换变量方法,而不用声明第三个变量:
const climbStairs = function(n) {
// 前两个值的返回结果
if (n === 1) return 1;
if (n === 2) return 2;
let a = 1,
b = 2;
for (var i = 3; i <= n; i++) {
[a, b] = [b, b + a];
}
return b;
};
console.log(climbStairs(3), climbStairs(4), climbStairs(5));
鼓励我一下:
觉得还不错的话,给我的点个star吧
- 浅谈UDP(数据包长度,收包能力,丢包及进程结构选择)
- WCF版的PetShop之三:实现分布式的Membership和上下文传递
- “高并发”问题如何解决?腾讯云一分钟配置的“黑科技”帮您
- 初探JavaScript(三)——JS带我"碰壁"带我飞
- 初探JavaScript(四)——作用域链和声明提前
- 开发人员看测试之运行Github中的JBehave项目
- 如何高效地合并Spark社区PR到自己维护的分支
- 开发人员看测试之TDD和BDD
- AngularJS入门心得1——directive和controller如何通信
- AngularJS入门心得2——何为双向数据绑定
- AngularJS入门心得3——HTML的左右手指令
- AngularJS入门心得4——漫谈指令scope
- Enterprise Library深入解析与灵活应用(8):WCF与Exception Handling AppBlock集成[上]
- 苹果就“电池门”公开致歉;微信下拉任务栏新增小游戏;美团打车进入北京
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- R语言基于Reactome数据库的富集分析
- WiredTiger存储引擎之五:与事务相关的数据结构以及并发控制机制
- Tomcat NIO(8)-Poller线程的阻塞与唤醒
- 你的第一个React App (一 ) - 项目初始化
- 被JDK坑的没商量?来试试这些方法吧
- k8s 代码走读---client-go 编程交互测试代码
- C#网络类智能开关控制板实例
- Flume拦截器实现按照事件时间接入HDFS
- Day4.Linux用户权限
- 如何使用Canal同步MySQL的Binlog到Kafka
- Go 每日一库之 gabs
- 如何将Flink应用的日志发送到kafka
- 锦囊篇|Java中的SPI机制
- webpack实战——生产环境配置【上】
- 深度阅读之《Concurrency in Go》