You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return
-1
.Input: coins = [1, 2, 5], amount = 11 Output: 3 Explanation: 11 = 5 + 5 + 1
Input: coins = [2], amount = 3 Output: -1
- You may assume that you have an infinite number of each kind of coin.
- mine
- Java
-
DFS & Recursion & BackTrack
Runtime: 58 ms, faster than 9.66%, Memory Usage: 36.8 MB, less than 99.87% of Java online submissions
int res = Integer.MAX_VALUE; public int coinChange(int[] coins, int amount) { if(amount <= 0){ return 0; } if (coins == null || coins.length == 0) { return -1; } if (coins.length == 1) { return amount % coins[0] == 0 ? amount / coins[0] : -1; } Arrays.sort(coins); dfs(coins, amount, coins.length - 1, 0); if (res == Integer.MAX_VALUE) { return -1; } return res; } public void dfs(int[] coins, int amount, int end, int count) { if (coins == null || amount < coins[0] || end < 0) { return; } for (int i = end; i >= 0; i--) { if (count > res) { return; } int d = amount / coins[i]; int m = amount % coins[i]; if (d > 0) { if (m == 0) { res = Math.min(res, count + d); return; } else if (i == 0) { return; } while (d >= 0) { if (count + d > res) { break; } dfs(coins, m, i - 1, count + d); d--; m += coins[i]; } } } }
-
DFS & Recursion & BackTrack Optimization
Runtime: 2 ms, faster than 99.39%, Memory Usage: 37 MB, less than 99.42% of Java online submissions
int res = Integer.MAX_VALUE; public int coinChange(int[] coins, int amount) { if (amount <= 0) { return 0; } if (coins == null || coins.length == 0) { return -1; } if (coins.length == 1) { return amount % coins[0] == 0 ? amount / coins[0] : -1; } Arrays.sort(coins); dfs(coins, amount, coins.length - 1, 0); return res == Integer.MAX_VALUE ? -1 : res; } public void dfs(int[] coins, int amount, int end, int count) { if (coins == null || amount < coins[0] || end < 0) { return; } for (int i = amount / coins[end]; i >= 0; i--) { int amountLeft = amount - i * coins[end]; int curCount = count + i; if (amountLeft == 0) { res = Math.min(res, curCount); break; } if (curCount + 1 >= res) { break; } dfs(coins, amountLeft, end - 1, curCount); } }
-
- Java
-
the most votes
-
Recursion & BackTrack
Runtime: 2 ms, faster than 99.39%,Memory Usage: 36.5 MB, less than 99.98% of Java online submissions
int total = Integer.MAX_VALUE; public int coinChange(int[] coins, int amount) { if (amount == 0) return 0; Arrays.sort(coins); count(amount, coins.length - 1, coins, 0); return total == Integer.MAX_VALUE ? -1 : total; } void count(int amount, int index, int[] coins, int count) { if (index < 0 || count >= total - 1) return; int c = amount / coins[index]; for (int i = c; i >= 0; i--) { int newCount = count + i; int rem = amount - i * coins[index]; if (rem > 0 && newCount < total) count(rem, index - 1, coins, newCount); else if (newCount < total) total = newCount; else if (newCount >= total - 1) break; } }
- leetcode
-
Dynamic programming - Top down
Runtime: 33 ms, faster than 17.98%,Memory Usage: 39.1 MB, less than 62.56% of Java online submissions
// O(N * L)time O(N)space // N = amount, L= coins.length public int coinChange(int[] coins, int amount) { if (amount < 1) { return 0; } return coinChange(coins, amount, new int[amount]); } private int coinChange(int[] coins, int rem, int[] count) { if (rem < 0) { return -1; } if (rem == 0) { return 0; } if (count[rem - 1] != 0) { return count[rem - 1]; } int min = Integer.MAX_VALUE; for (int coin : coins) { int res = coinChange(coins, rem - coin, count); if (res >= 0 && res < min){ min = 1 + res; } } count[rem - 1] = (min == Integer.MAX_VALUE) ? -1 : min; return count[rem - 1]; }
-
Dynamic programming - Bottom up
Runtime: 11 ms, faster than 86.24%, Memory Usage: 39 MB, less than 75.89% of Java online submissions
// O(N * L)time O(N)space // N = amount, L= coins.length public int coinChange(int[] coins, int amount) { int max = amount + 1; int[] dp = new int[amount + 1]; Arrays.fill(dp, max); dp[0] = 0; for (int i = 1; i <= amount; i++) { for (int j = 0; j < coins.length; j++) { if (coins[j] <= i) { dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); } } } return dp[amount] > amount ? -1 : dp[amount]; }
-