diff --git a/CoinChange.java b/CoinChange.java new file mode 100644 index 00000000..7a70f6c1 --- /dev/null +++ b/CoinChange.java @@ -0,0 +1,57 @@ +// Recursive TLE O(2^(m+n)) time, O(m+n) space +// class Solution { +// public int coinChange(int[] coins, int amount) { +// int ans = helper(0, coins, amount); +// if (ans == Integer.MAX_VALUE) return -1; +// return ans; +// } + +// public int helper(int i, int[] coins, int amount) { +// if (amount == 0) return 0; + +// if (i == coins.length || amount < 0) { +// return Integer.MAX_VALUE; +// } + +// int dontPickCoin = helper(i+1, coins, amount); + +// int pickCoin = Integer.MAX_VALUE; +// if (coins[i] <= amount) { +// int temp = helper(i, coins, amount - coins[i]); +// if (temp != Integer.MAX_VALUE) { +// pickCoin = 1 + temp; +// } +// } +// return Math.min(pickCoin, dontPickCoin); +// } +// } + +// Bottom up DP O(n * m) time, O(n * m) space +class Solution { + public int coinChange(int[] coins, int amount) { + int n = coins.length; + + int[][] dp = new int[n+1][amount+1]; + + dp[0][0] = 0; + + for (int i = 1; i <= amount; i++) { + dp[0][i] = Integer.MAX_VALUE-1; + } + + for (int i = 1; i <= n; i++) { + for (int j = 0; j <= amount; j++) { + if (coins[i-1] <= j) { // can pick + // min between pick and dont pick + dp[i][j] = Math.min(dp[i-1][j], 1 + dp[i][j - coins[i-1]]); + } + else { + // dont pick + dp[i][j] = dp[i-1][j]; + } + } + } + if (dp[n][amount] == Integer.MAX_VALUE-1) return -1; + return dp[n][amount]; + } +} diff --git a/HouseRobber.java b/HouseRobber.java new file mode 100644 index 00000000..925aee60 --- /dev/null +++ b/HouseRobber.java @@ -0,0 +1,33 @@ +// Recursive TLE O(2^n) time, O(n) space +// class Solution { +// public int rob(int[] nums) { +// return helper(0, nums); +// } + +// public int helper(int i, int[] nums) { +// if (i == nums.length) return 0; + +// int rob = nums[i] + helper(i+2, nums); + +// int dontRob = helper(i+1, nums); + +// return Math.max(rob, dontRob); +// } +// } + + +// Bottom up DP O(n) time, O(n) space +class Solution { + public int rob(int[] nums) { + int n = nums.length; + int[] dp = new int[n+1]; + + dp[0] = 0; + dp[1] = nums[0]; + + for (int i = 2; i <= n; i++) { + dp[i] = Math.max(dp[i-1], nums[i-1] + dp[i-2]); + } + return dp[n]; + } +}