From 298d87dddcf76cd9c7ad249b3926660bae350afb Mon Sep 17 00:00:00 2001 From: kiyan Date: Mon, 7 Mar 2016 13:38:30 -0800 Subject: [PATCH 1/2] first drop --- Medium/CoinChange.java | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Medium/CoinChange.java diff --git a/Medium/CoinChange.java b/Medium/CoinChange.java new file mode 100644 index 00000000..afd2a386 --- /dev/null +++ b/Medium/CoinChange.java @@ -0,0 +1,28 @@ +/** + * 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. + * + * Example 1: + * coins = [1, 2, 5], amount = 11 + * return 3 (11 = 5 + 5 + 1) + * + * Example 2: + * coins = [2], amount = 3 + * return -1. + * + * Note: + * You may assume that you have an infinite number of each kind of coin. + * + * Tags: Dynamic Programming + */ +class CoinChange { + + public int coinChange(int[] coins, int amount) { + + } + + public static void main(String[] args) { + + } +} From 6c72598253af3b8d0f78251bef11541cb6e1dcbb Mon Sep 17 00:00:00 2001 From: kiyan Date: Mon, 7 Mar 2016 15:34:57 -0800 Subject: [PATCH 2/2] add problem 322, 2 solutions --- Medium/CoinChange.java | 63 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/Medium/CoinChange.java b/Medium/CoinChange.java index afd2a386..1718141b 100644 --- a/Medium/CoinChange.java +++ b/Medium/CoinChange.java @@ -1,3 +1,7 @@ +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + /** * 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. @@ -18,11 +22,66 @@ */ class CoinChange { + int minCount = Integer.MAX_VALUE; + + /** + * backtracking + */ public int coinChange(int[] coins, int amount) { - + Arrays.sort(coins); // ascending order + backtrack(amount, coins.length - 1, coins, 0); + return minCount == Integer.MAX_VALUE ? -1 : minCount; + } + + private void backtrack(int amount, int index, int[] coins, int count) { + if (index < 0 || count + 2 > minCount) { + return; + } + for (int i = amount / coins[index]; i >= 0; i--) { + int newAmount = amount - i * coins[index]; // use as many biggest number as possible + int newCount = count + i; // update current count + if (newAmount > 0 && newCount + 1 < minCount) { + backtrack(newAmount, index - 1, coins, newCount); // next number + } else { // newAmount <= 0 || newCount+1 >= minCount + if (newAmount == 0 && newCount < minCount) { + minCount = newCount; // found current count, update minCount + } + break; + } + } + } + + /** + * memorize previous calculated amount + */ + Map map = new HashMap<>(); + + /** + * DP = recursive + memorize repeat calculation + * if current coin is included, minCount = 1 + coinChange(coins, amount - coinValue) + * minCount for some values are calculated repeatedly + */ + public int coinChange2(int[] coins, int amount) { + if (amount == 0) return 0; + if (map.containsKey(amount)) return map.get(amount); + + int count = Integer.MAX_VALUE; + for (int coin : coins) { // minCount for all coins + int curr = 0; // minCount for current coin + if (amount >= coin) { + int next = coinChange(coins, amount - coin); + if (next >= 0) curr = 1 + next; + } + if (curr > 0) count = Math.min(count, curr); + } + int minCount = count == Integer.MAX_VALUE ? -1 : count; + map.put(amount, minCount); + return minCount; } public static void main(String[] args) { - + CoinChange c = new CoinChange(); + int res = c.coinChange(new int[]{5, 2, 1}, 11); + System.out.println(res); } }