Problem:
Analysis:
Obviously, this is a DP problem. we can try to figure out it from two aspects. Top to bottom or bottom to Top.
The next step, we should reduce the time complexity and space complexity.
ONE time O(nm^2) space(nm)
TWO time O(nm) space(nm)
THREE time O(nm) space(m)
Code:
public int coinChange1(int[] coins, int amount) {
int[][] f = new int[coins.length + 1][amount + 1];
Arrays.fill(f[coins.length], Integer.MAX_VALUE);
f[coins.length][0] = 0;
for (int i=f.length-2;i>=0; i--) {
for (int j=0; j<=amount; j++) {
f[i][j] = f[i+1][j];
for (int k=1; k<=j/coins[i]; k++) {
int pre = f[i+1][j-k*coins[i]];
if (pre < Integer.MAX_VALUE) {
f[i][j] = Math.min( f[i][j], pre+k );
}
}
}
}
if (f[0][amount] == Integer.MAX_VALUE) {
return -1;
}else {
return f[0][amount];
}
}
public int coinChange2(int[] coins, int amount) {
int[][] f = new int[coins.length + 1][amount + 1];
Arrays.fill(f[coins.length], Integer.MAX_VALUE);
f[coins.length][0] = 0;
for (int i=f.length-2;i>=0; i--) {
for (int j=0; j<=amount; j++) {
f[i][j] = f[i+1][j];
if (j >= coins[i]) {
int pre = f[i][j-coins[i]];
if (pre < Integer.MAX_VALUE) {
f[i][j] = Math.min(f[i][j], pre+1);
}
}
}
}
if (f[0][amount] == Integer.MAX_VALUE) {
return -1;
}else {
return f[0][amount];
}
}
public int coinChange(int[] coins, int amount) {
int n = coins.length;
int[] g = new int[amount + 1];
Arrays.fill(g, Integer.MAX_VALUE);
g[0] = 0;
for (int i=coins.length-1; i>=0; i--) {
for (int j=0; j<=amount; j++) {
if (j >= coins[i]) {
int pre = g[j-coins[i]];
if (pre < Integer.MAX_VALUE) {
g[j] = Math.min(g[j], pre+1);
}
}
}
}
if (g[amount] == Integer.MAX_VALUE) {
return -1;
}else {
return g[amount];
}
}