Skip to content
DSAPrep

    ↑↓ to move · Enter to open · Esc to close

    Easy1-D DP

    Min Cost Climbing Stairs

    You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps.

    You can either start from the step with index 0, or the step with index 1.

    Return the minimum cost to reach the top of the staircase, which is the position just past the last step (index cost.length).

    Example 1

    Input: cost = [10,15,20]

    Output: 15

    Explanation: Start at index 1. Pay 15 and climb two steps to reach the top. Total cost is 15.

    Example 2

    Input: cost = [1,100,1,1,1,100,1,1,100,1]

    Output: 6

    Explanation: Start at index 0, and always climb two steps except the last one, paying 1 six times to land past the top.

    Constraints

    • 2 <= cost.length <= 1000
    • 0 <= cost[i] <= 999
    View original on LeetCode ↗

    Define dp[i] as the minimum cost to reach step i (not the cost of standing on it). You can arrive at step i from i-1 or i-2, and either way you had to pay whatever that previous step cost to leave it. So dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]), with dp[0] = dp[1] = 0 since you can start at either step for free. The answer is dp[n], the cost to reach just past the last step.

    Brute Force Recursion

    Time O(2ⁿ)Space O(n)

    Recurse forward: from step i, either pay cost[i] and jump 1, or pay cost[i] and jump 2. Take the cheaper branch, with the recursion bottoming out once i reaches or passes the top.

    class Solution:
    def minCostClimbingStairs(self, cost: list[int]) -> int:
    n = len(cost)
    def minCost(i: int) -> int:
    if i >= n:
    return 0
    return cost[i] + min(minCost(i + 1), minCost(i + 2))
    return min(minCost(0), minCost(1))

    Every call branches into two more calls, so the tree of recursive calls doubles in size with depth, giving O(2ⁿ) time despite massive overlap between subproblems (the same minCost(i) gets recomputed from many different paths).

    Top-Down Memoization

    Time O(n)Space O(n)

    Cache minCost(i) the first time it’s computed. There are only n distinct values of i, so once each is solved once, every later call is an O(1) lookup.

    class Solution:
    def minCostClimbingStairs(self, cost: list[int]) -> int:
    n = len(cost)
    memo = {}
    def minCost(i: int) -> int:
    if i >= n:
    return 0
    if i in memo:
    return memo[i]
    memo[i] = cost[i] + min(minCost(i + 1), minCost(i + 2))
    return memo[i]
    return min(minCost(0), minCost(1))

    O(n) distinct subproblems, each doing O(1) work beyond its (memoized) recursive calls → O(n) time. The memo dict and recursion depth both cost O(n) space.

    Bottom-Up DP

    OptimalTime O(n)Space O(n)

    Flip the recursion into a forward fill: dp[i] is the minimum cost to arrive at step i, computed left to right. dp[0] = dp[1] = 0 (free starting points), then dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]) for i from 2 to n.

    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]

    Trace for cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] (n = 10): watch the dp bar fill left to right as each step compares its two predecessor routes and keeps the cheaper one.

    cost[i] to leave step i

    0111002131415100617181009110·

    dp[i] min cost to arrive

    00102·3·4·5·6·7·8·9·10·

    choosing dp[i]

    via step i-1

    no candidates yet

    via step i-2

    no candidates yet
    1 / 10
    comparingresultdiscardedseen

    Base cases: dp[0] and dp[1] are both 0, because you may start on step 0 or step 1 before paying any cost to leave. Now fill dp left to right.

    One pass from 2 to n, constant work per step → O(n) time. The full dp array costs O(n) space here, but since each dp[i] only depends on the previous two entries, it can be shrunk to two rolling variables for O(1) space if desired.

    More 1-D DP practice