Loading problems...
TL;DR: The optimal solution uses Dynamic Programming to iteratively calculate the minimum cost to reach each step by comparing the costs of the two possible previous steps, ultimately determining the cheapest path to the top.
The Min Cost Climbing Stairs problem asks us to find the minimum cost to reach the top of a staircase. We are given an integer array cost where each element represents the cost to step off that specific stair. From any step i, we can move to i + 1 or i + 2. We are allowed to start our climb at either index 0 or index 1. The "top" of the floor is considered the position immediately after the last element of the array.
This is a classic optimization problem found in LeetCode 746. It serves as a foundational exercise for understanding state-based decision-making in algorithms.
The brute force approach attempts to solve the problem by exploring every possible path from the start (index 0 or 1) to the top. This is typically implemented using simple recursion. At every step , the function recursively calculates the cost of taking one step and the cost of taking two steps, adding the current step's cost to the minimum of those two future outcomes.
itextfunction minCost(i): if i >= length of cost: return 0 cost_one_step = minCost(i + 1) cost_two_steps = minCost(i + 2) return cost[i] + min(cost_one_step, cost_two_steps) return min(minCost(0), minCost(1))
The time complexity of this approach is O(2^n). Each call branches into two new recursive calls, creating a binary tree of execution. The space complexity is O(n) due to the recursion stack depth.
This approach fails due to overlapping subproblems. The algorithm repeatedly recalculates the minimum cost for the same steps. For example, to find the cost for step 0, it calculates step 2. To find the cost for step 1, it also calculates step 2. As n grows (up to 1000 in this problem), the number of redundant calculations explodes exponentially, leading to a Time Limit Exceeded (TLE) error.
The core insight that transitions us from the naive recursive approach to the optimal solution is the realization that we can reverse the direction of calculation. Instead of looking forward from the start, we can look backward from the destination (or build forward from the start iteratively).
To reach step i, there are exactly two possibilities:
i-1 and paid cost[i-1].i-2 and paid cost[i-2].Therefore, the minimum cost to reach step i is the minimum of these two scenarios. This establishes our recurrence relation (the "transition equation"):
Here, dp[i] represents the minimum accumulated cost to arrive at step i.
Visual Description:
Imagine an array dp of size n + 1. We know the cost to arrive at index 0 is 0 and index 1 is 0 (since we can start at either for free). To fill index 2, we look at the values at indices 0 and 1, add their respective traversal costs, and pick the smaller sum. We repeat this process linearly. The dependency graph is a straight line where node i only requires data from i-1 and i-2, allowing us to discard older data and optimize space.

Let's trace the algorithm with cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1].
Initialization:
prev2 (cost to reach index 0) = 0prev1 (cost to reach index 1) = 0cost array length n = 10.Iteration (i = 2 to 10):
prev2 (0) + cost[0] (1) = 1prev1 (0) + cost[1] (100) = 100prev2 becomes 0, prev1 becomes 1.prev2 (0) + cost[1] (100) = 100prev1 (1) + cost[2] (1) = 2prev2 becomes 1, prev1 becomes 2.prev2 (1) + cost[2] (1) = 2prev1 (2) + cost[3] (1) = 31+1=2 vs 2+1=3. Min is 2).prev2 becomes 2, prev1 becomes 2.Termination:
i reaches n. The variable prev1 holds the minimum cost to reach the "top".The correctness is guaranteed by mathematical induction.
k < i, our algorithm has correctly computed the minimum cost to reach step k. To reach step i, one must come from either i-1 or i-2. Since we compare the optimal cost of reaching i-1 (plus the cost to leave it) against the optimal cost of reaching i-2 (plus the cost to leave it), and we choose the minimum, the result for i must also be optimal.n is correct.cppclass Solution { public: int minCostClimbingStairs(vector<int>& cost) { int n = cost.size(); // Base cases: cost to reach index 0 is 0, index 1 is 0. int prev2 = 0; // Represents dp[i-2] int prev1 = 0; // Represents dp[i-1] for (int i = 2; i <= n; ++i) { // Cost to reach current step i // We pay cost[i-1] if coming from i-1 // We pay cost[i-2] if coming from i-2 int current = min(prev1 + cost[i - 1], prev2 + cost[i - 2]); // Shift pointers for next iteration prev2 = prev1; prev1 = current; } return prev1; } };
javaclass Solution { public int minCostClimbingStairs(int[] cost) { int n = cost.length; // Base cases implicitly handled: // To reach index 0: 0 cost // To reach index 1: 0 cost int prev2 = 0; // dp[i-2] int prev1 = 0; // dp[i-1] for (int i = 2; i <= n; i++) { int current = Math.min(prev1 + cost[i - 1], prev2 + cost[i - 2]); prev2 = prev1; prev1 = current; } return prev1; } }
pythonclass Solution: def minCostClimbingStairs(self, cost: List[int]) -> int: n = len(cost) # prev2 represents minimum cost to reach i-2 prev2 = 0 # prev1 represents minimum cost to reach i-1 prev1 = 0 for i in range(2, n + 1): # Calculate cost to reach current step i current = min(prev1 + cost[i - 1], prev2 + cost[i - 2]) # Shift variables for the next iteration prev2 = prev1 prev1 = current return prev1
Time Complexity: O(N)
We iterate through the cost array exactly once. Each iteration involves constant time operations (addition and comparison). N is the length of the cost array.
Space Complexity: O(1)
We optimized the solution to use only two integer variables (prev1 and prev2) to store the state, regardless of the input size. If we had used a full DP array, the space complexity would be O(N).
The DP - 1D Array (Fibonacci Style) pattern and its logic are directly applicable to several other popular interview questions:
min, you sum the ways to reach previous steps.dp[i] = max/min(dp[i-1], dp[i-2] + val) structure, but maximizes profit with a constraint that adjacent houses cannot be robbed.Why does the naive solution result in TLE?
Why is my answer wrong by the value of the last element?
dp[n-1] instead of calculating the cost to step off the last element.cost array.Can I just use a Greedy approach?