这是我的代码:
class Solution {
std::unordered_map<int, int> um;
public:
int coinChange(vector<int>& coins, int amount) {
if (amount == 0)
return 0;
auto it = um.find(amount);
if (it != um.end())
return it->second;
int ret = -1;
for (int c : coins)
{
int n = 1;
while (true)
{
int a = amount - n * c, m = 0;
if (a < 0)
break;
if (a > 0)
m = coinChange(coins, a);
if (m != -1)
{
if (ret == -1)
ret = m + n;
else
ret = std::min(ret, m + n);
}
n++;
}
}
um[amount] = ret;
return ret;
}
};
据我所知,它与最受欢迎的解决方案非常相似,它甚至构造了相同的哈希表 . 但是我在任意输入时都会超时 . 我无法在本地找到任何错误 .
什么想法可能是错的?
编辑:
我包括问题陈述:
您将获得不同面额的硬币和总金额 . 编写一个函数来计算构成该数量所需的最少数量的硬币 . 如果这笔钱不能由任何硬币组合弥补,则返回-1 .
示例:coins = [1,2,5],金额= 11返回3(11 = 5 5 1)
该方法:
使用动态编程(递归记忆) . 对于金额,只要金额是正数,就尝试每一枚硬币 . 对于上面的例子:
S(11) = 1 + S(10) | 2 + S(9) | 3 + S(8) | ... | 11 + S(0) | //try coin 1
1 + S(9) | 2 + S(7) | 3 + S(5) | ... | 5 + S(1) | //try coin 2
1 + S(6) | 2 + S(1) //try coin 5
请原谅这个问题的混乱,我相信我对上述想法的实现有一些错误,但我很难找到它 .
1 回答
Later edit: I was wrong
我注意到C版本的运行时间仍然太高,所以这不是问题 . 我设法从Leetcode获得所有测试并发现了问题 .
对于测试案例硬币:{3,7,405,436}和金额:8839我的实施将拨打18744855电话,而最受欢迎的只有34486 .
这是因为,对于每个硬币,我尝试尽可能多地将其放入数量(
while (true)
循环),并且在每次尝试之后我进行递归调用 . 它是这样的(对于coin = {1}和amount = 3):然而,只需尝试一次硬币并让递归调用处理剩下的就足够了,就像流行的解决方案一样:
Previous answer:
我已经将相同的解决方案移植到C,并且已被接受,因此我认为这是Leetcode基础结构中的一些问题 .