You are given an array of integers cost where cost[i] is the cost of taking a step from the ith floor of a staircase. After paying the cost, you can step to either the (i + 1)th floor or the (i + 2)th floor.
You may choose to start at the index 0 or the index 1 floor.
Return the minimum cost to reach the top of the staircase, i.e. just past the last index in cost.
Example 1:
Input: cost = [1,2,3]
Output: 2Explanation: We can start at index = 1 and pay the cost of cost[1] = 2 and take two steps to reach the top. The total cost is 2.
Example 2:
Input: cost = [1,2,1,2,1,1,1]
Output: 4Explanation: Start at index = 0.
cost[0] = 1 and take two steps to reach index = 2.cost[2] = 1 and take two steps to reach index = 4.cost[4] = 1 and take two steps to reach index = 6.cost[6] = 1 and take one step to reach the top.4.Constraints:
2 <= cost.length <= 1000 <= cost[i] <= 100
You should aim for a solution as good or better than O(n) time and O(n) space, where n is the number of steps on the staircase.
Can you find the recurrence relation to solve the problem, given that at each step we have two options: going one step or two steps? Consider drawing a decision tree where we branch into two paths at each step. By exploring every path, we can get the minimum cost. However, this results in an O(2^n) time solution. Can you think of a better approach? Is there any repeated work in the decision tree that we can optimize?
The recurrence relation can be expressed as cost[i] + min(dfs(i + 1), dfs(i + 2)), where i is the current position and dfs is the recursive function. To avoid recalculating the result of a recursive call multiple times, we can use Memoization. Initialize a cache array of size n, where n is the number of steps on the staircase. How would you implement this?
We start the recursion from positions 0 and 1. At each recursive step, before computing the result, we check if the result for the current position has already been calculated. If it has, we return the stored value. Otherwise, we calculate the result for the current position, store it in the cache, and then return the result. What can be the base condition for this recursion to stop?
The base condition would be to return 0 if we are at the top of the staircase i >= n. This is a one-dimensional dynamic programming problem. We can further optimize the memoization solution by using advanced techniques such as Bottom-Up dynamic programming based on the recurrance relation.
Before attempting this problem, you should be comfortable with:
From any step, you can climb 1 or 2 steps.
If you step on index i, you must pay cost[i], then choose the cheaper path ahead.
So the problem is: from each step, pick the minimum cost path to the top.
dfs(i) = minimum cost to reach the top starting from step i.i is beyond the last step, cost is 0 (you reached the top).cost[i]1 step → dfs(i + 1)2 steps → dfs(i + 2)0 or 1, return:min(dfs(0), dfs(1))The brute force solution recomputes the same subproblems many times.
We can optimize it by remembering results once we compute them.
For each step i, the minimum cost to reach the top is:
cost[i] + minimum cost from step i+1 or i+2By storing this result, we avoid repeated work.
memo array where memo[i] stores the minimum cost to reach the top from step i.dfs(i):i is beyond the last step, return 0.memo[i] is already computed, return it.memo[i] = cost[i] + min(dfs(i+1), dfs(i+2))0 or 1, return:min(dfs(0), dfs(1))Instead of solving the problem recursively, we build the answer from the bottom up.
Let dp[i] represent the minimum cost to reach step i.
To reach step i, you can:
i-1 and pay cost[i-1]i-2 and pay cost[i-2]We choose the cheaper of the two.
n be the number of steps.dp of size n+1.dp[0] = 0, dp[1] = 0 (you can start at step 0 or 1 for free).i from 2 to n:dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])dp[n] as the minimum cost to reach the top.At each step, you only need the minimum cost of the next one or two steps.
So instead of using a full DP array, we can reuse the input array and update it in place.
Each cost[i] is updated to represent:
the minimum cost to reach the top starting from step
i.
By the end, the answer is simply the minimum cost starting from step 0 or 1.
i:cost[i] = cost[i] + min(cost[i+1], cost[i+2])min(cost[0], cost[1]) since you can start from either.The top of the staircase is at index n (one step past the last stair), not at index n-1. You need to reach beyond the last step, so your DP array or recursion must account for landing on position n, not just visiting the last cost element.
The problem allows starting from either step 0 or step 1 without paying any cost initially. A common mistake is assuming you must start from step 0 only, which can lead to suboptimal solutions when starting from step 1 would be cheaper.
When using bottom-up DP, the base cases should be dp[0] = 0 and dp[1] = 0 because you can stand on step 0 or step 1 for free before paying to move forward. Setting these incorrectly, such as dp[0] = cost[0], misinterprets when you pay the cost.