leetcode:Coin Change
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.
分析:题意为给你不同面值的硬币和总金额数,写一个函数去计算构成这个总金额所需的最小的硬币数目。如果硬币的任何组合都不能构成总钱数就返回-1。
思路:很明显的DP问题,一开始在想是否可以使用贪心算法,发现这样是不能保证最小coin数目的,例如:amount = 8, coins为[1, 3, 5, 6],采用贪心策略得到3(6,1,1),而实际上正确值为2(5,3),之所以贪心法在这里不适用是因为贪心所作的决策并不能确保全局最优,如果换作问题为提水,每桶都有一定量的水,怎样才能最少次数运完所有的水,这样可以用贪心选择最多的水,因为每次提越多的水,到最后的次数肯定最少。
本题两种解决办法,但是思想是一样的
:
1、使用线性规划法,dp[n]为amount为n的change数目,那么我们从dp[1]开始就可以DP到dp[n],迭代关系式为,dp[n] = min(dp[n], dp[n-coins[m]]+1).
2、使用递归的方法,不过有可能会造成memory exceed,递推关系为count(n,m,coins) = min(count(n,m-1,coins), count(n-coins[m],m,coins)); 其中count表示寻找最少change的函数,n为amount,m为coins(排好序的)的下标。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Solution { public : int coinChange(vector< int >& coins, int amount) { if (!coins.size() && amount) return -1; vector< int > dp(amount + 1, INT_MAX); dp[0] = 0; for ( auto coin : coins) { for ( int i = coin; i <= amount; ++i) { if (dp[i-coin] != INT_MAX) { dp[i] = min(dp[i], dp[i - coin] + 1); } } } return dp[amount] == INT_MAX?-1:dp[amount]; } }; |
参考方法2:the first recursive DFS solution
Just use the array to record the previous computed states.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class Solution { public : int coinChange(vector< int >& coins, int amount) { if (amount<1) return 0; vector< int > dp(amount, 0); return help(coins, amount, dp); } int help(vector< int >& coins, int remain, vector< int >& dp){ if (remain<0) return -1; if (remain==0) return 0; if (dp[remain-1]!=0) return dp[remain-1]; int min=INT_MAX; for ( int coin : coins){ int result=help(coins, remain-coin, dp); if (result>=0 && result<min) min=1+result; } dp[remain-1]=(min==INT_MAX ? -1 : min); return dp[remain-1]; } }; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理