在问 · 算法题解

746. 使用最小花费爬楼梯

题目描述

输入整数数组 cost,长度为 n。站在第 i 级台阶上时,支付 cost[i] 后可以向上走 1 级或 2 级。

起点可以选第 0 级或第 1 级,选起点本身不花钱。楼顶是下标为 n 的位置,即越过最后一级台阶。

返回到达楼顶所需的最小总花费。

示例 1
输入:cost = [10,15,20]
输出:15

解释:从第 1 级起步,付 15 直接跨两级到楼顶。

示例 2
输入:cost = [1,100,1,1,1,100,1,1,100,1]
输出:6

解释:从第 0 级起步,一路避开花费为 100 的台阶,共付 6 次 1。

数据范围

  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999

解题思路

设 dp[i] 为到达第 i 级(还没付第 i 级的费用)的最小花费。到达 i 只有两种来路:从 i-1 付 cost[i-1] 爬一级,或从 i-2 付 cost[i-2] 爬两级,取较小者。起点可以任选 0 或 1,所以 dp[0] = dp[1] = 0。

为什么正确

循环到 i 时,dp[0..i-1] 都已是到达对应台阶的最小花费。

复杂度分析

时间 O(n),空间 O(n)(只保留两个变量可降到 O(1))。

易错点

楼顶是下标 n,不是 n-1。返回 dp[n-1] 或 min(cost) 都会出错。另外要付的是“离开的那级”的费用 cost[i-1] / cost[i-2],不是 cost[i]。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        dp = [0] * (n + 1)
        for i in range(2, n + 1):
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
        return dp[n]

载入编辑器,自己跑一遍 →

动态规划 专题的其他题目

查看 动态规划 全部题目 →