题目:
第一次思考:
- 想用递归分解子问题实现
- 不出意外的超时了
实现:
class Solution {
public:
int amountCoin(vector<int>& coins, int amount)
{
if (amount<=0) return 0;
if (find(coins.begin(),coins.end(),amount)!=coins.end())
{
return 1;
}
int num=INT_MAX;
for (auto c:coins)
{
if (amount-c<coins[0]) continue;
num=min(amountCoin(coins,amount-c)+amountCoin(coins,c),num);
}
if (num==INT_MAX) num=-1;
return num;
}
int coinChange(vector<int>& coins, int amount) {
int ref=amountCoin(coins,amount);
return ref;
}
};
第二次思考
- 既然分解了子问题,那就采用动态规划降低时空复杂度
- 使用自顶向下动态规划👇(相当于记忆搜索);
class Solution {
public :
vector<int> dp;
public:
int coinsNums(vector<int>& coins, int amount)
{
if (amount<0) return -1;
if (amount==0) return 0;
if (dp[amount]!=0) return dp[amount];
int temp=INT_MAX;
for (auto c:coins)
{
int n=coinsNums(coins,amount-c);
if (n>=0)
{
temp=min(temp,n+1);
}
}
dp[amount]=temp==INT_MAX?-1:temp;
return temp==INT_MAX?-1:temp;
}
int coinChange(vector<int>& coins, int amount) {
dp.resize(amount+1,0);
dp[0]=0;
for (auto c:coins)
{
if (c<=amount)
{
dp[c]=1;
}
}
int ref=coinsNums(coins,amount);
return ref;
}
};
第三次思考:
- 使用自底向上动态规划👇可以再省些和空间
实现:
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int ref=0;
if (amount==0) return 0;
vector<int> dp(amount+1,-1);
for (auto c:coins)
{
if (c<=amount)
dp[c]=1;
}
dp[0]=0;
for (int i=0;i<=amount;i++)
{
int temp=INT_MAX;
for (auto c:coins)
{
if (i-c<0) continue;
if (dp[i-c]!=-1)
temp=min(dp[i-c]+dp[c],temp);
}
if (temp!=INT_MAX)
{
dp[i]=temp;
}
}
return dp[amount];
}
};