Skip to content
Open

DP-2 #1779

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions coin_change_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
time - o(n)
space - o(n)

"""

from typing import List


class Solution:
def change(self, amount: int, coins: List[int]) -> int:
dp = [[0] * (amount + 1) for _ in range(len(coins) + 1)]
for i in range(len(dp)):
dp[i][0] = 1
for i in range(1, len(dp)):
for j in range(1, len(dp[0])):
coin = coins[i - 1]
dp[i][j] = dp[i - 1][j]
if coin <= j:
dp[i][j] += dp[i][j - coin]

return dp[-1][-1]
65 changes: 65 additions & 0 deletions paint_houses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
time - o(n)
space o(n)
we take a look at the problem as only one row of houses, in this case we just take the minimum. The same problem space is increased
by adding another row of houses, we then for the second row have to look at each paint cost and add the min paint cost from the previous row
without the current paint id. Finally, at the last row we just return the min.
"""

from typing import List
import copy


class Solution:
def minCost(self, costs: List[List[int]]) -> int:
dp = copy.deepcopy(costs)
for i in range(1, len(costs)):
for j in range(len(costs[0])):
if j == 0:
dp[i][j] += min(dp[i - 1][1], dp[i - 1][2])
if j == 1:
dp[i][j] += min(dp[i - 1][0], dp[i - 1][2])
if j == 2:
dp[i][j] += min(dp[i - 1][0], dp[i - 1][1])
return min(dp[-1])


"""
recursive with memoization
time - o(n) without memo it is o(2^n) as we make a choice at every instance between two other paint costs but with memoization we only make
x number of calculations and store the result. Here x is 3 * 2 * n where 3 is the paint choices, 2 is the number of choices we make
at each node.
space o(n)

we start at the top row and make all three paint choices and call the helper function, helper function goes down the rows recursively
and carries the previous choice and index along with cost and dict as parameters. Once the paint cost is calculated (min of the other two paint choices based on previous selection)
we store it based on previous selection and current index in the memo

"""


class Solution2:
def minCost(self, costs: List[List[int]]) -> int:
if len(costs) == 1:

return min(costs[0])
memo = {}
cost = float("inf")
for i in range(len(costs[0])):
cost = min(cost, self.helper(costs, i, 1, costs[0][i], memo))
return cost

def helper(self, costs, prev_selection, index, curr_cost, memo):
if (prev_selection, index) in memo:
return memo[(prev_selection, index)]
if index == len(costs):
return curr_cost
next_cost = float("inf")
for i in range(len(costs[index])):
if i != prev_selection:
next_cost = min(
next_cost, self.helper(costs, i, index + 1, costs[index][i], memo)
)
total_cost = next_cost + curr_cost
memo[(prev_selection, index)] = total_cost
return total_cost