小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
算法学习是一个长期的学习过程, 算法题型也是有很多变化, 但是相同题型的变种有些解题技巧是一样的. 本文来学习一个相对简单的题型: 爬楼梯问题
动态规划
动态规划 基本思想: 问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。
简单点理解就是: 动态规划是把一个大问题拆解成一堆小问题, 而答案就是这一堆小问题答案的集合.
动态规划问题往往和其他算法思想有一定的联系, 比如 递归等. 虽然看起来很简单, 但是如何找到所有的可能值, 并且在这些可能值尽量减少重复的重叠子问题的计算才是一个难点.
比如 爬楼梯 n 层楼梯, 一次可爬一层 或两层, 就是这么简单的描述, 看起来简单, 但是真要找到准确的答案却不简单.
爬楼梯问题
LeetCode 70: 先看图吧, 比较好理解, 但是解决问题就没有昨天那个问题那么简单了. LeetCode 定义为 中等.
题目描述:
假设你正在爬楼梯。需要 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 阶
题解思路分析:
- 先看下执行时间 及结果
JavaScript解题代码:
/**
* @param {number} n
* @return {number}
*/
var climbStairs = function (n) {
// dp[i] 为第 i 阶楼梯有多少种方法爬到楼顶
// dp[i] = dp[i - 1] + dp[i - 2]
let dp = [1, 2]
for (let i = 2; i < n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n - 1]
}
解法复杂度:
- 时间复制度:
O(n)n 为 要爬的台阶数 - 空间复杂度:
O(1)