思路:动态规划。对于属于coins的coin,只要知道amount-coin至少需要多少个货币就能表示,那么amount需要的货币数目=amount-coin需要的货币数目+1;如果amount-coin都不能被表示,amount也不能被表示。
方法一:递归,由上至下。
1 class Solution { 2 Map<Integer, Integer> hashMap = new HashMap<>(); 3 public int coinChange(int[] coins, int amount) { 4 hashMap.put(0, 0);//0元不需要被货币表示 5 if(hashMap.containsKey(amount)) return hashMap.get(amount); 6 int curMin = amount + 1;//货币的最小面值只能是1,所以最多能被表示成amount个货币,那么amount+1就相当于正无穷 7 for(int coin : coins) { 8 if(amount >= coin) { 9 int cur = coinChange(coins, amount - coin) + 1; 10 if(cur > 0 && curMin > cur) curMin = cur;//cur==0就意味着amount-coin不能被当前货币表示 11 } 12 } 13 if(curMin == amount + 1) {//已经遍历过的元素的表示数目要及时记录 14 hashMap.put(amount, -1); 15 }else { 16 hashMap.put(amount, curMin); 17 } 18 return hashMap.get(amount); 19 } 20 }
Next challenges:
方法二:递推,由下至上。
1 class Solution { 2 Map<Integer, Integer> hashMap = new HashMap<>(); 3 public int coinChange(int[] coins, int amount) { 4 hashMap.put(0, 0);//0元不需要被货币表示 5 int MAX = amount + 1; 6 for(int i = 1; i <= amount; i++) { 7 hashMap.put(i, MAX);//面值为i能被表示成货币的数目的最小值 8 for(int coin : coins) { 9 if(i >= coin) { 10 hashMap.put(i, Math.min(hashMap.get(i), hashMap.get(i - coin) + 1)); 11 } 12 } 13 } 14 //对于面值i,只要i映射的值大于i就相当于i不能被当前的货币表示 15 return hashMap.get(amount) > amount ? -1 : hashMap.get(amount); 16 } 17 }