-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dynamic Programming House Robber abd Coin Change
- Loading branch information
Showing
2 changed files
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* Dynamic programming top down approach | ||
*/ | ||
|
||
// Time Complexity: O (N*K) N=coins, K=amount | ||
// Space Complexity: O (K) due to memoization | ||
// Did this code successfully run on Leetcode : Yes | ||
|
||
public class CoinChange_LC322 { | ||
public int coinChange(int[] coins, int amount) { | ||
//Handle empty input | ||
if (coins == null || coins.length == 0 || amount == 0) | ||
return 0; | ||
|
||
/** | ||
* Approach 1 with 2D memoization | ||
* Keep a 2D array that keeps track of min coins needed for each denomination to reach amount | ||
* The answer will be located at last row and column of dp array | ||
*/ | ||
/*int[][] dp = new int[coins.length + 1][amount + 1]; // DP array | ||
for (int i = 0; i < coins.length + 1; i++) dp[i][0] = 0; // 0 coins used to reach 0 amount | ||
for (int i = 0; i < amount + 1; i++) dp[0][i] = amount + 1; // infinite coins of 0 needed to reach amount | ||
for (int i = 1; i < coins.length + 1; i++) { | ||
for (int j = 1; j < amount + 1; j++) { | ||
if (j < coins[i - 1]) // Denomination more than amount to be reached | ||
dp[i][j] = dp[i - 1][j]; // Use previous subproblem's solution | ||
else | ||
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - coins[i - 1]] + 1); // take min of new soln vs prev subproblem soln | ||
} | ||
} | ||
return dp[coins.length][amount] < amount + 1 ? dp[coins.length][amount] : -1; // value is inf, there's no soln*/ | ||
|
||
/** | ||
* Approach 2 with 1D memoization; avoid 2D array since we need only one previous row for calculating subproblem's soln | ||
* Keep a 1D array that keeps track of min coins needed to reach intermediate amountsØ | ||
* The answer will be located at last index of dp array | ||
*/ | ||
int[] dp = new int[amount + 1]; // DP array | ||
|
||
for (int i = 0; i < amount + 1; i++) // Initialize array to infinity: amount + 1 | ||
dp[i] = amount + 1; | ||
|
||
dp[0] = 0; // 0 coins used to reach 0 amount | ||
|
||
for (int i = 1; i < amount + 1; i++) { | ||
for (int coin : coins) { | ||
if (coin <= i) | ||
dp[i] = Math.min(dp[i], 1 + dp[i - coin]); | ||
} | ||
} | ||
return dp[amount] > amount ? -1 : dp[amount]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* Use Dynamic Programming memoization and initialize a dp array with size n+1 | ||
* such that ith index will correspond to stealing ith house | ||
* 0th index: no house, 1st index: 1st house, ..., nth index: nth house | ||
* <p> | ||
* For maximizing dollars, go bottom up filling max stolen value at ith index of dp array | ||
* At any point use previously calculated max robbed value and find maximum of including current house or including previous | ||
*/ | ||
|
||
// Time Complexity: O (N) | ||
// Space Complexity: O (1) due to memoization | ||
// Did this code successfully run on Leetcode : Yes | ||
public class HouseRobber_LC198 { | ||
public int rob(int[] nums) { | ||
if (nums == null || nums.length == 0) | ||
return 0; | ||
|
||
/** Approach 1 Using 1D DP array | ||
* Keep filling DP array by taking current house and solution till that point into consideration | ||
* Answer lies at last index of DP array | ||
*/ | ||
/*int[] dp = new int[nums.length + 1]; // DP array | ||
dp[0] = 0; | ||
dp[1] = nums[0]; | ||
for (int i = 2; i <= nums.length; i++) { | ||
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]); // Choose max between prev solution and previous to previous solution plus current house | ||
} | ||
return dp[nums.length];*/ | ||
|
||
/** Approach 2 without DP array | ||
* At each house, you either choose it or don't | ||
* Keep 2 varibles to keep track of maximum house amount robbed when house was chosen or when it wasn't | ||
*/ | ||
int choose = 0, noChoose = 0; | ||
for (int num : nums) { | ||
int temp = noChoose; | ||
noChoose = Math.max(choose, noChoose); | ||
choose = temp + num; | ||
} | ||
return Math.max(choose, noChoose); | ||
} | ||
} |