Skip to content

Commit af027ba

Browse files
committed
Min cost climbing stairs
1 parent b11d667 commit af027ba

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# 746. Min cost climbing stairs
2+
# Topics: 'Array', 'Dynamic Programming'
3+
4+
# 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.
5+
6+
# You can either start from the step with index 0, or the step with index 1.
7+
8+
# Return the minimum cost to reach the top of the floor.
9+
10+
11+
12+
# Example 1:
13+
14+
# Input: cost = [10,15,20]
15+
# Output: 15
16+
# Explanation: You will start at index 1.
17+
# - Pay 15 and climb two steps to reach the top.
18+
# The total cost is 15.
19+
20+
# Example 2:
21+
22+
# Input: cost = [1,100,1,1,1,100,1,1,100,1]
23+
# Output: 6
24+
# Explanation: You will start at index 0.
25+
# - Pay 1 and climb two steps to reach index 2.
26+
# - Pay 1 and climb two steps to reach index 4.
27+
# - Pay 1 and climb two steps to reach index 6.
28+
# - Pay 1 and climb one step to reach index 7.
29+
# - Pay 1 and climb two steps to reach index 9.
30+
# - Pay 1 and climb one step to reach the top.
31+
# The total cost is 6.
32+
33+
34+
35+
# Constraints:
36+
37+
# 2 <= cost.length <= 1000
38+
# 0 <= cost[i] <= 999
39+
40+
from typing import List
41+
42+
43+
class Solution:
44+
def minCostClimbingStairs(self, cost: List[int]) -> int:
45+
memo = [-1]*(len(cost)+1)
46+
return min(self.climb(0, cost, memo), self.climb(1, cost, memo))
47+
48+
def climb(self, i: int, cost: List[int], memo: List[int]) -> int:
49+
if i < len(cost):
50+
if memo[i] != -1:
51+
return memo[i]
52+
memo[i] = cost[i] + min(self.climb(i+1, cost, memo), self.climb(i+2, cost, memo))
53+
return memo[i]
54+
else:
55+
return 0
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import unittest
2+
from cost import Solution
3+
4+
class TestMinCostClimbingStairs(unittest.TestCase):
5+
def setUp(self):
6+
self.s = Solution()
7+
8+
def test_example_1(self):
9+
cost = [10, 15, 20]
10+
expected = 15
11+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
12+
13+
def test_example_2(self):
14+
cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
15+
expected = 6
16+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
17+
18+
def test_two_elements_take_cheapest(self):
19+
cost = [5, 3]
20+
expected = 3
21+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
22+
23+
def test_two_elements_equal(self):
24+
cost = [7, 7]
25+
expected = 7
26+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
27+
28+
def test_increasing_costs(self):
29+
cost = [1, 2, 3, 4, 5]
30+
# Best: 2 + 4 = 6
31+
expected = 6
32+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
33+
34+
def test_decreasing_costs(self):
35+
cost = [10, 8, 6, 4, 2]
36+
# Best: start 1 → skip → 3 → skip → top = 8 + 4 = 12
37+
expected = 12
38+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
39+
40+
def test_zero_costs(self):
41+
cost = [0, 0, 0, 0]
42+
expected = 0
43+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
44+
45+
def test_large_values(self):
46+
cost = [999] * 20
47+
# Always just pick any consistent route: all same → 999 * ceil(n/2)
48+
expected = 999 * 10
49+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
50+
51+
def test_single_step_zero_then_big(self):
52+
cost = [0, 100, 0, 100, 0]
53+
expected = 0
54+
self.assertEqual(self.s.minCostClimbingStairs(cost), expected)
55+
56+
57+
if __name__ == "__main__":
58+
unittest.main()

0 commit comments

Comments
 (0)