题目描述
给你一个整数数组 coins
,表示不同面额的硬币;以及一个整数 amount
,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1
。
你可以认为每种硬币的数量是无限的。
示例 1:
1 2 3
| 输入:coins = [1, 2, 5], amount = 11 输出:3 解释:11 = 5 + 5 + 1
|
解题思路
- 暴力解 超时
- 加备忘录
执行用时:142 ms, 在所有 Java 提交中击败了5.00%的用户
内存消耗:43.3 MB, 在所有 Java 提交中击败了5.08%的用户
通过测试用例:189 / 189
时间 O(N)
空间 O(N)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { HashMap<Integer,Integer> map=new HashMap(); public int coinChange(int[] coins, int amount) { return getChange(coins,amount);
} public int getChange(int[] coins, int amount){ if(amount<0)return -1; if(amount==0)return 0; if(map.containsKey(amount))return map.get(amount); int ans=Integer.MAX_VALUE; for(int i:coins){ int tmp=getChange(coins,amount-i); if(tmp==-1)continue; ans=Math.min(ans,tmp+1); } ans = ans==Integer.MAX_VALUE?-1:ans; map.put(amount,ans); return ans; } }
|
- 自底向上,dp数组迭代,来自题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| int coinChange(int[] coins, int amount) { int[] dp = new int[amount + 1]; Arrays.fill(dp, amount + 1);
dp[0] = 0; for (int i = 0; i < dp.length; i++) { for (int coin : coins) { if (i - coin < 0) { continue; } dp[i] = Math.min(dp[i], 1 + dp[i - coin]); } } return (dp[amount] == amount + 1) ? -1 : dp[amount]; }
|