diff --git a/CoinChange_II.py b/CoinChange_II.py new file mode 100644 index 00000000..730483ab --- /dev/null +++ b/CoinChange_II.py @@ -0,0 +1,36 @@ +''' +To solve this problem, I chose exhaustive approach by building a DP table +- Initially I stored first row and column with dummy values +- As long as the coin denomination is greater than the amount the case would be invalid +- If its not less, we calculate the number of ways, by taking its repeated sub problems which calculate the number of ways and add them +''' +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + + n = len(coins) # rows + m = amount # columns + + # creating a DP table of n+1 rows(coins) and m+1 columns(amount) + dp = [[0] * (m+1) for _ in range(n+1)] + dp[0][0] = 1 # making first element as 1/ there is only 1 way to make zero amount, by not choosing any coin + + for i in range(1, n+1): + for j in range (m+1): + # till denomination > amount, case would be invalid + if coins[i-1] > j: + # so we copy the result from above row + dp[i][j] = dp[i-1][j] + else: + # filling current element with addition of: + # above row elemet (sub problem calculating part of no of ways) + # and element in the denominations steps back element(sub problem calculating part of no of ways) + dp[i][j] = dp[i-1][j] + dp[i][j-coins[i-1]] + # returning the last elemet which has no of ways to calculate the amount + return dp[n][m] + +''' +Time Complexity: O(n*m) +Since we are iterating on the DP table of size (n+1) * (m+1), we ignore the constants so O(n*m) +Space Complexity: O(m*n) +Since DP tables stores the results of all the coins count and amount +''' diff --git a/HousePaint.py b/HousePaint.py new file mode 100644 index 00000000..1662d58d --- /dev/null +++ b/HousePaint.py @@ -0,0 +1,34 @@ +''' +For solving the House Paint problem, I considered using exahustive approach by optimizing the sub problems. +- Initially I kept the costs of last row constant, and stored in the DP matrix in the last row. +- Then by iterating in the houses and colors matrix from bottom elements to top, I calculated the sum of current element and minimum cost of either of the colors. +- After filling the DP matrix, we return the minimum of top most row elements, because by the time the elements are +''' +class Solution: + def minCost(self, costs): + # no of rows/houses + n = len(costs) + # n houses and 3 columns + dp = [[0] * 3 for _ in range(n)] + # keeping the last row as it is + dp[n-1][0] = costs[n-1][0] + dp[n-1][1] = costs[n-1][1] + dp[n-1][2] = costs[n-1][2] + + # filling the dp matrix from second last index, since the last row already has same values from costs matrix + for i in range(n-2, -1, -1): + # filling the elements with cost of that color with minimum of other two colors from below row + # eg:taking the cost of painting the houses with red and cost of painting with minimum of blue/green + dp[i][0] = costs[i][0] + min(dp[i+1][1], dp[i+1][2]) + dp[i][1] = costs[i][1] + min(dp[i+1][0], dp[i+1][2]) + dp[i][2] = costs[i][2] + min(dp[i+1][0], dp[i+1][1]) + + # minimum of top most row + return min(dp[0][0], dp[0][1], dp[0][2]) + +''' +Time Complexity: O(n) +Here I am creating a DP matrix whose size is n*3, where 3 is constant, so we itearte on n elements which takes O(n) +Space Complexity: O(n) +Similarly for space the size of DP matrix would be n*3, where 3 is constant, so the average space taken is O(n) +''' \ No newline at end of file