From dcb56487a4e5d9efe738dbcc0ee5edb70d0eccb7 Mon Sep 17 00:00:00 2001 From: Tanmay Nalawade Date: Thu, 16 Oct 2025 19:19:53 -0700 Subject: [PATCH 1/3] Problem 518 complete --- .qodo/518. Coin Change II.py | 70 ++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .qodo/518. Coin Change II.py diff --git a/.qodo/518. Coin Change II.py b/.qodo/518. Coin Change II.py new file mode 100644 index 00000000..8050c1d3 --- /dev/null +++ b/.qodo/518. Coin Change II.py @@ -0,0 +1,70 @@ +# Time: O(2^m+n) => m is the amount and n is the no. of elements in coins array +# The time complexity is when we choose until amount is 1 and then we don't choose until the idx is not out of range +# Space: O(m+n) => That's the recursive space that will be used at the end + +# Everything is similar to coin change except returning choose + not_choose because we have to count all the possible paths +# Hence we have also changes the base cases accordingly so if amount is 0 it's valid and returns 1 and rest is invalid path which returns 0 +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + return self.helper(coins, amount, 0) + def helper(self,coins,amount,idx): + # Base case + if amount == 0: + return 1 + if idx > (len(coins) - 1) or amount < 0: + return 0 + + # choose + choose = self.helper(coins,amount-coins[idx],idx) + # Not choose + not_choose = self.helper(coins,amount,idx+1) + + return choose + not_choose + +# MEMOIZATION SOLUTION +# Time and Space: O(m * n) where m is the len(coins) and n is the amount + +# Just add the values calculate (choose + not_choose) in a memo matrix and use the same amount for repeated sub problems +# Add the result in the memo matrix i.e the additioin of choose and not_choose +# return self.memo[idx][amount] from the function +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + self.memo = [[-1 for _ in range(amount + 1)] for _ in range(len(coins) +1)] + + return self.helper(coins, amount, 0) + def helper(self,coins,amount,idx): + # Base case + if amount == 0: + return 1 + if idx > (len(coins) - 1) or amount < 0: + return 0 + if self.memo[idx][amount] != -1: + return self.memo[idx][amount] + + # choose + choose = self.helper(coins,amount-coins[idx],idx) + # Not choose + not_choose = self.helper(coins,amount,idx+1) + + self.memo[idx][amount] = choose + not_choose + return self.memo[idx][amount] + + +# TABULARISATION SOLUTION +# Time and Space: O(m * n) where m is the len(coins) and n is the amount +class Solution: + def change(self, amount: int, coins: List[int]) -> int: + rows = len(coins) + cols = amount + dp_matrix = [[0 for _ in range(cols + 1)] for _ in range(rows + 1)] + + for i in range(1,rows + 1): + for j in range(0,cols + 1): + if j == 0: + dp_matrix[i][j] = 1 + elif j < coins[i-1]: + dp_matrix[i][j] = dp_matrix[i - 1][j] + else: + dp_matrix[i][j] = dp_matrix[i - 1][j] + dp_matrix[i][j-coins[i - 1]] + + return dp_matrix[rows][cols] From 16b597697f4af9b7aa0636e12c5ef88bfc445b8e Mon Sep 17 00:00:00 2001 From: Tanmay Nalawade Date: Thu, 16 Oct 2025 19:34:40 -0700 Subject: [PATCH 2/3] update the directory --- .qodo/518. Coin Change II.py => 518. Coin Change II.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .qodo/518. Coin Change II.py => 518. Coin Change II.py (100%) diff --git a/.qodo/518. Coin Change II.py b/518. Coin Change II.py similarity index 100% rename from .qodo/518. Coin Change II.py rename to 518. Coin Change II.py From 2494fcbc7248c755b8d477ccca3308ff736bc970 Mon Sep 17 00:00:00 2001 From: Tanmay Nalawade Date: Sun, 19 Oct 2025 17:35:39 -0700 Subject: [PATCH 3/3] Problem 256 completed --- 256. Paint House.py | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 256. Paint House.py diff --git a/256. Paint House.py b/256. Paint House.py new file mode 100644 index 00000000..958bd1b1 --- /dev/null +++ b/256. Paint House.py @@ -0,0 +1,59 @@ +# EXHAUSTIVE SOLUTION + +# Time: O(2^n) n=> number of houses +# Space: O(n) As the recursion depth is only till the length of costs i.e the number of rows which determines the houses + +# Loop through the number of colors +# check in the helper function which color we use and use the remaining colors +# Check whats the cost of minimum between the two colors and add the current cost in it +class Solution: + def minCost(self, costs: List[List[int]]) -> int: + min_val = float('inf') + for n in range(len(costs[0])): + min_val = min(min_val, self.helper(costs, 0, n)) + return min_val + + def helper(self, costs, idx, n): + # base + if idx == len(costs): + return 0 + + # Logic + if n == 0: + choose_blue = self.helper(costs, idx + 1, n + 1) + choose_green = self.helper(costs, idx + 1, n + 2) + + return costs[idx][n] + min(choose_blue, choose_green) + elif n == 1: + choose_red = self.helper(costs, idx + 1, n - 1) + choose_green = self.helper(costs, idx + 1, n + 1) + + return costs[idx][n] + min(choose_red, choose_green) + else: + choose_red = self.helper(costs, idx + 1, n - 2) + choose_blue = self.helper(costs, idx + 1, n - 1) + + return costs[idx][n] + min(choose_red, choose_blue) + + + +# MEMOISATION SOLUTION +# Time: O(3n) => which is O(n) because we have 3 colors and n number of houses +# Space: O(3n) => which is O(n) we crate a matrix of n * number of colors + +# Just put everything in a memo matrix and use it to optimise on time + +class Solution: + def minCost(self, costs: List[List[int]]) -> int: + memo = [[-1 for _ in range(3)] for _ in range(len(costs))] + for m in range(len(costs) -1, -1, -1 ): + if m == len(costs) - 1: + memo[m][0] = costs[m][0] + memo[m][1] = costs[m][1] + memo[m][2] = costs[m][2] + else: + memo[m][0] = costs[m][0] + min(memo[m+1][1], memo[m+1][2]) + memo[m][1] = costs[m][1] + min(memo[m+1][0], memo[m+1][2]) + memo[m][2] = costs[m][2] + min(memo[m+1][0], memo[m+1][1]) + + return min(memo[0][0], memo[0][1],memo[0][2]) \ No newline at end of file