diff --git a/coin-change.java b/coin-change.java new file mode 100644 index 00000000..d861f3a7 --- /dev/null +++ b/coin-change.java @@ -0,0 +1,60 @@ +// Solution - 1 + +// TimeComplexity: O(m*n) where m is coins length and n is amount +// SpaceComplexity: O(n) +// Explanation: I am using dynamic programming to build the answer from smaller subproblems. I create a 1D array matrix where matrix[k] represents the minimum number of coins needed to make amount k. +// For each coin, I iterate through all amounts and update the minimum coins required using the relation matrix[k] = min(matrix[k], 1 + matrix[k - coin]). +// In the end, if the value at matrix[amount] is still very large, it means the amount cannot be formed, so I return -1. +class Solution { + public int coinChange(int[] coins, int amount) { + int m = coins.length; + int[] matrix = new int[amount+1]; + for(int i=1; i=coins[j-1]) { + matrix[k] = Math.min(matrix[k], 1+matrix[k-coins[j-1]]); + } + } + } + + if(matrix[amount] > Integer.MAX_VALUE-100) return -1; + return matrix[amount]; + + + } +} + + +// Solution -2 + +// TimeComplexity:(2^(m+n)) where m is coins length and n is amount +// SpaceComplexity: O(m+n) +// Explnation: Here I use recursion to try all possible combinations. At each step, I have two choices: either take the current coin (reduce amount) or skip it (move to next coin). +// I recursively compute both choices and return the minimum. If the amount becomes negative or I exhaust all coins, I return a large value to indicate invalid. +class Solution { + public int coinChange(int[] coins, int amount) { + int result= helper(coins, amount, 0); + if (result>=Integer.MAX_VALUE-10) return -1; + return result; + + } + + private int helper(int[] coins, int amount, int idx) { + // base + if(idx==coins.length||amount<0) return Integer.MAX_VALUE-10; + if(amount==0) return 0; + + // choose + int choice1 = 1+ helper(coins, amount-coins[idx], idx); + + + // no choose + int choice2 = helper(coins, amount, idx+1); + + return Math.min(choice1, choice2); + } +} \ No newline at end of file diff --git a/house-robber.java b/house-robber.java new file mode 100644 index 00000000..e2524b60 --- /dev/null +++ b/house-robber.java @@ -0,0 +1,82 @@ +// Solution - 1 + +// TimeComplexity: O(n) +// SpaceComplexity: O(n) +// Explanation: I am using dynamic programming to store the maximum money that can be robbed up to each house. +// The array dp[i] represents the maximum money I can rob from the first i houses. +// For each house, I decide whether to skip it (dp[i-1]) or rob it (nums[i-1] + dp[i-2]) and take the maximum of the two. Finally, dp[nums.length] gives the answer. +class Solution { + public int rob(int[] nums) { + int [] dp = new int[nums.length+1]; + dp[1] = nums[0]; + + for(int i=2; i=nums.length) return 0; + if(dp[idx]!=null) { + return dp[idx]; + } + + + // no choose + int case1 = helper(nums, idx+1, dp); + + + // choose + int case2= nums[idx] + helper(nums, idx+2, dp); + + int max = Math.max(case1, case2); + dp[idx] = max; + + return max; + + } +} + +// Solution - 3 +// TimeComplexity: O(2ⁿ) +// SpaceComplexity: O(n) (recursion stack) +// Explanation: In this version, I recursively try both choices (rob or skip) at every house without storing results. +// This causes repeated calculations of the same subproblems, leading to exponential growth in calls. +class Solution { + public int rob(int[] nums) { + return helper(nums, 0); + + } + + private int helper (int[] nums, int idx) { + // base + if(idx>=nums.length) return 0; + + + // no choose + int case1 = helper(nums, idx+1); + + + // choose + int case2= nums[idx] + helper(nums, idx+2); + + return Math.max(case1, case2); + + } +}