标签:return min int coins 零钱 amount 兑换 Leetcode322 dp
思路:
一开始想起来的就是给现有的零钱进行排序,然后选取最大面值的零钱,进行回溯,找到就立即退出,这样的做法没有考虑到1,7,10 amount = 14这种情况,10,1,1,1,1与7,7肯定是最少两个硬币。如果说遍历所有的情况,不提前退出,会出现超时的情况。那么回溯的时候不用每次都只减一个coins[i],而是每次减个amount/coins[i]coins[i],这样的话也不行,没有考虑到2,4,5 amount= 11这种情况,因为一次性减25的话,由于找不到1,结果就是-1,其实结果应该是2,4,5,结果为3
所以这道题用dfs是需要花费些心思的,还需要进行剪枝来防止超时的发生。
class Solution {
int min = Integer.MAX_VALUE;
public int coinChange(int[] coins, int amount) {
Arrays.sort(coins);
helper(coins,amount,0,coins.length-1);
if(min == Integer.MAX_VALUE){
return -1;
}else{
return min;
}
}
public void helper(int[] coins,int amount,int count,int index){
if(amount == 0){
min = Math.min(min,count);
return;
}
if(index < 0) return;
for(int k = amount/coins[index];k >= 0 && k + count < min;k--){//剪枝条件
helper(coins,amount-k*coins[index],count+k,index-1);
}
}
}
第二种做法就是使用动态规划方法
f(i)为为实现为i的钱数需要多少硬币,总共的硬币面额为2,3,4
f(1) = min(f(1-2),f(1-3),f(1-4))+1;
f(2)= min(f(2-2),f(2-3),f(2-4))+1;
f(3)=min(f(3-2),f(3-3),f(3-4))+1;
.
.
.
f(i) = min(f(i-2),f(i-3),f(i-4))+1;
class Solution {
int min = Integer.MAX_VALUE;
public int coinChange(int[] coins, int amount) {
// Arrays.sort(coins);
int[] dp = new int[amount+1];
Arrays.fill(dp,amount+1);
dp[0] = 0;
for(int i = 1;i <= amount;i++){
for(int j = 0;j < coins.length;j++){
if(i >= coins[j]){
dp[i] = Math.min(dp[i],dp[i-coins[j]]+1);
}
}
}
return dp[amount] == amount+1? -1:dp[amount];
}
}
标签:return,min,int,coins,零钱,amount,兑换,Leetcode322,dp 来源: https://blog.csdn.net/fsdgfsf/article/details/104737505
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。