Ⅰ:凑零钱问题:
①给出不重复的数组 coins 表示硬币的面额,数字 amount 表示需要凑成的金额。如果每种金额的硬币只能用一次,输出所有不重复的可能的组合的总数。
递归:
class Solution {
private:
int helper(vector<int>& coins, int index, int amount)
{
if(amount == 0) return 1;
if(amount < 0 || index >= coins.size()) return 0;
int res = 0;
for (int i = index; i < coins.size(); ++i)
{
if(amount < coins[i]) continue;
res += helper(coins, i + 1, amount - coins[i]);
}
return res;
}
public:
int change(int amount, vector<int>& coins) {
return helper(coins, 0, amount);
}
};
② 如果每种金额的硬币只能使用一次,但是不同的选用顺序被认为是不同的组合,例如{1,2}和{2,1}被认为是不同的组合,输出所有可能的组合的总数。
递归:
class Solution {
private:
vector<bool> used;
int helper(vector<int>& coins, int amount)
{
if(amount == 0) return 1;
if(amount < 0) return 0;
int res = 0;
for (int i = 0; i < coins.size(); ++i)
{
if(amount < coins[i] || used[i]) continue;
used[i] = true;
res += helper(coins, amount - coins[i]);
used[i] = false;
}
return res;
}
public:
int change(int amount, vector<int>& coins) {
used = vector<bool>(coins.size(), false);
return helper(coins, amount);
}
};
③ 如果每种金额的硬币能够重复使用,输出所有不重复的可能组合的总数:
递归:
class Solution {
private:
int helper(vector<int>&coins, int index, int amount)
{
if(amount == 0) return 1;
if(amount < 0 || index >= coins.size()) return 0;
int res = 0;
for (int i = 0; i * coins[index]<= amount; ++i)
{
res += helper(coins, index + 1, amount - i * coins[index]);
}
return res;
}
public:
int change(int amount, vector<int>& coins) {
return helper(coins, 0, amount);
}
};
④ 如果每种金额的硬币能够重复使用,并且不同的取用顺序被认为是不同的组合,例如 {1,2} 和 {2 , 1}看作不同的组合,输出所有可能组合的总数:
递归:
class Solution {
private:
int helper(vector<int>&coins, int amount)
{
if(amount == 0) return 1;
if(amount < 0) return 0;
int res = 0;
for (int i = 0; i < coins.size(); ++i)
{
res += helper(coins, amount - coins[i]);
}
return res;
}
public:
int change(int amount, vector<int>& coins) {
return helper(coins, amount);
}
};
⑤ 如果每种金额的硬币能够重复使用,输出能够组成 amount 的最少元素的数量,如果不能组成amount, 输出-1。
递归:
class Solution {
private:
int maxNum;
int helper(vector<int>& coins, int amount)
{
if(amount == 0) return 0;
if(amount < 0) return maxNum;
int res = maxNum;
for (int i = 0; i < coins.size(); ++i)
{
if(amount < coins[i]) continue;
res = min(res, 1 + helper(coins, amount - coins[i]));
}
return res;
}
public:
int coinChange(vector<int>& coins, int amount) {
maxNum = amount + 1;
int ret = helper(coins, amount);
return ret == maxNum ? -1 : ret;
}
};
⑥ 如果每种金额的硬币只能使用1次,输出能够组成 amount 的最少元素的数量,如果不能组成 amount,输出 -1。
递归:
class Solution {
private:
int maxNum;
int helper(vector<int>& coins, int amount, int index)
{
if(amount == 0) return 0;
if(amount < 0 || index >= coins.size()) return maxNum;
int res = maxNum;
for (int i = index; i < coins.size(); ++i)
{
if(amount < coins[i]) continue;
res = min(res, 1 + helper(coins, amount - coins[i], i + 1));
}
return res;
}
public:
int coinChange(vector<int>& coins, int amount) {
maxNum = amount + 1;
int ret = helper(coins, amount, 0);
return ret == maxNum ? -1 : ret;
}
};