Optimize Dynamic Programming
Optimize space and remove corner cases
Example: Leetcode 518. Coin Change 2 1) Original Code:
// dp[i][j] number of combinations to make up of amount i with coins[0]:coins[j];
// dp[i][j] = with coins[j] to combine + without coins[j] to combine
public int change(int amount, int[] coins) {
if(amount==0) return 1;
if(coins.length==0) return 0;
int dp[][] = new int[amount+1][coins.length];
for(int i=1; i<=amount; i++) {
for(int j=0;j<coins.length;j++) {
int withCoinJ = 0;
if(i<coins[j]) withCoinJ=0;
else if(i==coins[j]) withCoinJ=1;
else withCoinJ=dp[i-coins[j]][j];
if(j==0) dp[i][0] += withCoinJ; // use coins[j]
else dp[i][j] = withCoinJ+dp[i][j-1]; //without using coins[j]
}
}
return dp[amount][coins.length-1];
}
2) Remove Corner case: Expand dp array size to cover corner cases In this case, we increase j. We should do the following:
Increase dp[] size from j to j+1
Shift variable j in for loop by 1
Shift all the table[j] to table[j-1] in the j for loop
Remove duplicated corner case checking
Return dp[j+1]
// dp[i][j+1] number of combinations to make up of amount i with coins[0]:coins[j]; // dp[i][j+1] = with coins[j] to combine + without coins[j] to combine public int change(int amount, int[] coins) { if(amount==0) return 1; if(coins.length==0) return 0; int dp[][] = new int[amount+1][coins.length+1];//change for(int i=1; i<=amount; i++) { for(int j=1;j<=coins.length;j++) { // change to j=[1,coins.length] int withCoinJ = 0; if(i<coins[j-1]) withCoinJ=0; // change else if(i==coins[j-1]) withCoinJ=1; // change table[j] else withCoinJ=dp[i-coins[j-1]][j]; dp[i][j] = withCoinJ+dp[i][j-1]; } } return dp[amount][coins.length]; // change }
3) Decrease Dimension: Change the loop sequence Can we decrease the rp from two dimension to one dimension? We can see that dp[][j] only depends on dp[][j-1], while dp[i][] depends on dp[0:i-1][]
Switch the j and i loop
// dp[i][j+1] number of combinations to make up of amount i with coins[0]:coins[j]; // dp[i][j+1] = with coins[j] to combine + without coins[j] to combine public int change(int amount, int[] coins) { if(amount==0) return 1; if(coins.length==0) return 0; int dp[][] = new int[amount+1][coins.length+1];//change for(int j=1;j<=coins.length;j++) { for(int i=1; i<=amount; i++) { int withCoinJ = 0; if(i<coins[j-1]) withCoinJ=0; // change else if(i==coins[j-1]) withCoinJ=1; // change table[j] else withCoinJ=dp[i-coins[j-1]][j]; dp[i][j] = withCoinJ+dp[i][j-1]; } } return dp[amount][coins.length]; // change }
Remove the dimension that is associated with j
public int change(int amount, int[] coins) { if(amount==0) return 1; if(coins.length==0) return 0; int dp[] = new int[amount+1];//change for(int j=1;j<=coins.length;j++) { for(int i=1; i<=amount; i++) { int withCoinJ = 0; if(i<coins[j-1]) withCoinJ=0; else if(i==coins[j-1]) withCoinJ=1; else withCoinJ=dp[i-coins[j-1]]; // change dp[i] = withCoinJ + dp[i]; // change } } return dp[amount]; // change }
Check if we can remove corner cases' condition
public int change(int amount, int[] coins) { int dp[] = new int[amount+1]; dp[0] = 1; //change for(int j=1;j<=coins.length;j++) { for(int i=1; i<=amount; i++) { int withCoinJ = 0; if(i<coins[j-1]) withCoinJ=0; // change else withCoinJ=dp[i-coins[j-1]]; dp[i] = withCoinJ + dp[i]; } } return dp[amount];
Question:
Leetcode 188. Best Time to Buy and Sell Stock IV
Reverse thinking: think from end to beginning
Situation
When the following dp table can affect the previous filling dp table.
Question:
Leetcode 312. Burst Balloons
Last updated