THN Interview Prep

746. Min Cost Climbing Stairs

At a Glance

  • Topic: dp-1d
  • Pattern: Dynamic Programming (linear minimum cost)
  • Difficulty: Easy
  • Companies: Amazon, Google, Adobe, Uber, Bloomberg
  • Frequency: High
  • LeetCode: 746

Problem (one-liner)

Each stair index has a non-negative cost[index]. Pay that cost to step onto it; start at index 0 or 1. Reach past the last index with minimum total cost. Input: cost array. Output: minimum sum.

Recognition Cues

  • “Minimum cost” + “from step i you can go to i+1 or i+2
  • Start position choice (first or second stair)
  • Top is beyond last index (pay once then exit)

Diagram

At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.

Loading diagram…

Approaches

  • Brute force — enumerate all paths — exponential time.
  • Better — top-down memo from each index — O(n) time / O(n) space.
  • Optimal — bottom-up min of two predecessors — O(n) time / O(1) space. <- pick this in interview.

Optimal Solution

Go

package main

func minCostClimbingStairsTable(cost []int) int {
	length := len(cost)
	dp := make([]int, length+1)
	dp[0], dp[1] = 0, 0
	for index := 2; index <= length; index++ {
		payCurrent := dp[index-1] + cost[index-1]
		payPrevious := dp[index-2] + cost[index-2]
		if payCurrent < payPrevious {
			dp[index] = payCurrent
		} else {
			dp[index] = payPrevious
		}
	}
	return dp[length]
}

func minCostClimbingStairs(cost []int) int {
	length := len(cost)
	prevPrev := 0
	prev := 0
	for index := 2; index <= length; index++ {
		payCurrent := prev + cost[index-1]
		payPrevious := prevPrev + cost[index-2]
		next := payCurrent
		if payPrevious < payCurrent {
			next = payPrevious
		}
		prevPrev = prev
		prev = next
	}
	return prev
}

JavaScript

function minCostClimbingStairsTable(cost) {
	const length = cost.length;
	const dp = new Array(length + 1).fill(0);
	for (let index = 2; index <= length; index++) {
		dp[index] = Math.min(
			dp[index - 1] + cost[index - 1],
			dp[index - 2] + cost[index - 2]
		);
	}
	return dp[length];
}

function minCostClimbingStairs(cost) {
	const length = cost.length;
	let prevPrev = 0;
	let prev = 0;
	for (let index = 2; index <= length; index++) {
		const next = Math.min(
			prev + cost[index - 1],
			prevPrev + cost[index - 2]
		);
		prevPrev = prev;
		prev = next;
	}
	return prev;
}

Walkthrough

Input: cost = [10, 15, 20]

index (landing)from index-1from index-2dp[index]
00
10
20+10=100+0 invalid — use 0 from start10
310+15=250+10=1010

Reach past index 2 with cost 10.

Invariant: dp[index] is min cost to stand on step index (or 0 for virtual start); transition always adds cost of the stair you step onto.

Edge Cases

  • Length 2: answer is min(cost[0], cost[1])
  • All zeros → answer 0
  • Large costs still fit in int for typical constraints

Pitfalls

  • Adding cost of stair you leave instead of stair you land on
  • Confusing “top” as last index instead of one past last
  • Allocating dp of length n only — need n+1 for destination past last stair

Similar Problems

Variants

  • Variable jump lengths → longer rolling window or full table.
  • Must land exactly on last stair (no “past top”) → shift indices in recurrence.

Mind-Map Tags

#dp-1d #linear-dp #min-cost-path #rolling-state #easy

Last updated on

Spotted something unclear or wrong on this page?

On this page