Leetcode 70 爬楼梯
动态规划
题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
解题思路
当台阶数有 1 层时,有 1 种方法
当台阶数有 2 层时,有 2 种方法
当台阶数有 n 层时,有 ? 种方法
当我第一次爬上第 1 层台阶时,还有 n-1 层,有对应的 p 种方法
当我第一次爬上第 2 层台阶时,还有 n-2 层,有对应的 q 种方法
所以,当台阶数 >= 3时,就有 f(n-1) + f(n-2) 种方法
那么得出:
解题代码
第一种解法 递归
var climbStairs = function(n) {
if(n === 1) return 1
if(n === 2) return 2
return climbStairs(n-1) + climbStairs(n-2)
}
时间复杂度:O(n2),LeetCode报超出时间限制。
第二种解法 递归优化
我们发现在递归过程中,比如现在有6层台阶,会求2遍 f(4),那么我们做个优化,把已经求过的f(n)放到map中。
var map = new Map()
var climbStairs = function(n) {
if(n === 1) return 1
if(n === 2) return 2
if(map.has(n)) {
map.get(n)
} else {
let res = climbStairs(n-1) + climbStairs(n-2)
map.set(n, res)
return res
}
}
第三种解法 循环
之前是从 自顶向下 的推导 [ f(6) --> f(1)/f(2) ],这次我们从下向上推导,当求 f(3) 时,方法为 f(1) + f(2)种,当求 f(4) 时,方法为 f(2) + f(3) 种,也就是说 求 f(3) 用到了 f(2), 求 f(4) 用到刚才求出的 f(3) 和之前求出的 f(2),使用两个变量存 f(3) 和 f(2),每次循环求时迭代相加即可得出结果。
var climbStairs = function(n) {
if(n === 1) return 1
if(n === 2) return 2
let res = 0
let n1 = 1
let n2 = 2
for(let i = 3; i <= n; i++) {
res = n1 + n2
n1 = n2
n2 = res
}
return res
}
相同题目:剑指 Offer 10- I. 斐波那契数列
题目描述:
这题和爬楼梯很相似,区别在于: 当 res 大于 1000000007 时,需要对结果取余。
/**
* @param {number} n
* @return {number}
*/
var fib = function(n) {
const mod = 1000000007
if(n < 2) return n
let res = 0
let n1 = 0
let n2 = 1
for(let i = 2; i <= n; i++) {
res = (n1 + n2) % mod
n1 = n2
n2 = res
}
return res
};
图片来源:【【Leetcode算法500题】目前B站最完整的数据结构算法教程,包含所有刷题攻略!这还没人看,我不更了!-哔哩哔哩】 b23.tv/8jMxHQi