算法学习解题技巧-动态规划-爬楼梯问题

319 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

算法学习是一个长期的学习过程, 算法题型也是有很多变化, 但是相同题型的变种有些解题技巧是一样的. 本文来学习一个相对简单的题型: 爬楼梯问题

动态规划

动态规划 基本思想: 问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。

简单点理解就是: 动态规划是把一个大问题拆解成一堆小问题, 而答案就是这一堆小问题答案的集合.

动态规划问题往往和其他算法思想有一定的联系, 比如 递归等. 虽然看起来很简单, 但是如何找到所有的可能值, 并且在这些可能值尽量减少重复的重叠子问题的计算才是一个难点.

比如 爬楼梯 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)