leetcode:Coin Change
来源:互联网 发布:数据加密不属于计算 编辑:程序博客网 时间:2024/05/22 13:24
原题:
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.
题意:给一些不同面额的硬币和一个数值,给出能凑出这个面额的最少的硬币数量。
解题思路:这个题很容易想到用动态规划,我的思路是,先凑出两个比这个数值小的数,然后由这两个数再凑成这个数值(在实现时遍历了所有的这样的两个数),因为是动态规划,凑这两个数值比较小的数的硬币数是可以知道的。这个算法虽然是动态规划,但是复杂度也是O(amount^2),而且空间复杂度是O(amount),结果超时。
其实总体思路是对的,但错在“遍历所有的这样的两个数”,应该是去遍历所有的硬币,而不是数,因为硬币数量远小于数值。这种算法时间复杂度是O(amount*coins.length)。
动态规划的核心思想是假设有2,3,5三种面额,需要凑成amount,那么一定是取 1+(amount-2),1+(amount-3),1+(amount-5)这三种数量中最少的,对于(amount-2),(amount-3)和(amount-5)的计算,是递归向下进行的。
代码如下:
public static int coinChange(int[] coins, int amount) { if (coins == null || coins.length == 0 || amount <= 0) return 0; int[] minNumber = new int[amount + 1]; for (int i = 1; i <= amount; i++) { minNumber[i] = Integer.MAX_VALUE; for (int j = 0; j < coins.length; j++) { //遍历所有的硬币面额 if (coins[j] <= i && minNumber[i - coins[j]] != Integer.MAX_VALUE) //要判断是否可以生成这个面额 minNumber[i] = Integer.min(minNumber[i], 1 + minNumber[i - coins[j]]); } } if (minNumber[amount] == Integer.MAX_VALUE) return -1; else return minNumber[amount];}
上面思路的空间复杂度是O(amount)。
还有一种递归的实现方式,空间复杂度应该小于上者,但是比上面慢多了。在使用递归的动态规划中,使用了HashMap来保存已经计算过的数据,从而避免了重复计算,理论上说使用HashMap保存时,空间复杂度会降低。总的思路跟上面类似。
代码如下:
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();//dp还可以用hashMap存放已经计算的数据,第一次尝试 public int coinChange(int[] coins, int amount) { if(amount==0){ return 0; } for(int coin:coins){ map.put(coin, 1); } int res = getCoins(coins, amount); if(res==Integer.MAX_VALUE){ return -1; } return res; } //获取指定数目的钱,需要多少硬币 public int getCoins(int[] coins,int amount){ if(map.containsKey(amount)){ return map.get(amount); } int minVal = Integer.MAX_VALUE; for(int coinVal:coins){ int cur = minVal; if(amount>coinVal){ cur = getCoins(coins, amount-coinVal); } if(minVal>cur){ minVal = cur; } } if(minVal!=Integer.MAX_VALUE){ map.put(amount, minVal+1); return minVal+1; }else{ map.put(amount, Integer.MAX_VALUE); return Integer.MAX_VALUE; } }
- leetcode Coin Change
- Leetcode: Coin Change
- LeetCode Coin Change
- [leetcode] 322. Coin Change
- Leetcode: Coin Change
- [LeetCode 322] Coin Change
- leetcode--Coin Change
- [leetcode]Coin Change
- leetcode 322. Coin Change
- leetcode:Coin Change
- leetcode之Coin Change
- Leetcode 322. Coin Change
- Leetcode 322. Coin Change
- leetcode笔记:Coin Change
- leetcode 322 Coin Change
- 322. Coin Change LeetCode
- 【LeetCode-322】Coin Change
- leetcode之 coin change
- ZOJ-3380 Patchouli's Spell Cards(概率DP&&大数)
- android 用户登陆注册UI设计之 edittext (就是输入用户名和密码的文本框)
- SQL 养成一个好习惯是一笔财富
- 打开命令行的特殊姿势
- vim编辑器入门教程
- leetcode:Coin Change
- poj1053 模拟
- jQuery的选择器
- 【步兵 c++】 多态&虚函数
- 简单BashGame博弈 初尝试
- Linux每天学习一个命令之type命令
- XMG 事件传递的调用 当事件传递给控件的时候就会调用,去寻找最合适的View,
- Android Studio 基本设置
- 《java入门第一季》之面向对象