Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我的leetcode 322硬币解决方案会更改超时_C++_Algorithm - Fatal编程技术网

C++ 为什么我的leetcode 322硬币解决方案会更改超时

C++ 为什么我的leetcode 322硬币解决方案会更改超时,c++,algorithm,C++,Algorithm,这是我的密码: 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())

这是我的密码:

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;
    }
};

请原谅我对这个问题的困惑,我相信我对上述想法的实施有一些缺陷,但我很难找到它。

稍后编辑:我错了

我注意到C版本的运行时间仍然太长,所以这不是问题所在。我设法从Leetcode获得了所有测试,并发现了问题

对于测试用例coins:{3,7,405,436}和amount:8839,我的实现将进行18744855次调用,而最流行的只有34486次

这是因为,对于每一枚硬币,我会尽可能多次地将其放入数量中(while(true)循环),每次尝试后,我都会进行递归调用。它是这样的(对于硬币={1}和数量=3):

但是,只需尝试一次硬币,然后让递归调用处理其余部分就足够了,就像流行的解决方案一样:

S(3) = min{1 + S(2)}

S(2) = min{1 + S(1)}

S(1) = min{1 + S(0)}

S(0) = 0
先前的答案:

我已经将相同的精确解决方案移植到了C中,并且得到了认可,因此我认为这是Leetcode基础架构中的一些问题

int coinChange_(int* coins, int coinsSize, int *um, int amount) {
    if (amount == 0)
        return 0;

    if (um[amount] != 0)
        return um[amount];

    int ret = -1;

    for (int i = 0; i < coinsSize; i++)
    {
        int c = coins[i];
        int n = 1;
        while (true)
        {
            int a = amount - n * c, m = 0;
            if (a < 0)
                break;
            if (a > 0)
                m = coinChange_(coins, coinsSize, um, a);
            if (m != -1)
            {
                if (ret == -1)
                    ret = m + n;
                else
                    ret = m + n < ret ? m + n : ret;
            }
            n++;
        }
    }

    um[amount] = ret;
    return ret;
}

int coinChange(int* coins, int coinsSize, int amount) {
    int *um = calloc(amount + 1, sizeof *um);
    int ret = coinChange_(coins, coinsSize, um, amount);
    free(um);
    return ret;
}
int coinChange_u2;(int*coins,int coinsize,int*um,int amount){
如果(金额=0)
返回0;
如果(um[金额]!=0)
返回um[金额];
int-ret=-1;
for(int i=0;i0)
m=货币变化(货币,货币化,嗯,a);
如果(m!=-1)
{
如果(ret==-1)
ret=m+n;
其他的
ret=m+n
a是否可以是0?看起来如果是0,你的代码将永远循环。尝试使用调试器并逐步完成代码…如果你想从事软件开发人员的职业,那么最好远离那些虚假的竞争性编程网站。他们传播有害的知识,却毫无贡献。@mame98,我这样做了,我在运行单个输入时,无论是在本地还是在web界面上,都没有发现任何问题。那些有竞争力的编程网站接受任何碰巧通过测试的垃圾程序。他们并没有真正教你如何正确地编写程序。你发现了解决方案是很好的。但是在C++版本中,你使用了无序的映射,发现元素会增加时间复杂度,如果你将代码增量移植到C++,而不是直接跳转到试图获得<代码>无序的映射>代码>工作。如果
um
是一个非本地
std::vector
,并且只调用
resize()
来调整向量大小,您会发现您的
coinChange
函数可能会运行得更快。现在,您正在调用
calloc
free
,如果多次调用
coinChange
,这会增加所需的时间。@PaulMcKenzie,我知道这一点。我发现了真正的问题并更新了答案。这是算法中的一个微妙缺陷。
S(3) = min{1 + S(2)}

S(2) = min{1 + S(1)}

S(1) = min{1 + S(0)}

S(0) = 0
int coinChange_(int* coins, int coinsSize, int *um, int amount) {
    if (amount == 0)
        return 0;

    if (um[amount] != 0)
        return um[amount];

    int ret = -1;

    for (int i = 0; i < coinsSize; i++)
    {
        int c = coins[i];
        int n = 1;
        while (true)
        {
            int a = amount - n * c, m = 0;
            if (a < 0)
                break;
            if (a > 0)
                m = coinChange_(coins, coinsSize, um, a);
            if (m != -1)
            {
                if (ret == -1)
                    ret = m + n;
                else
                    ret = m + n < ret ? m + n : ret;
            }
            n++;
        }
    }

    um[amount] = ret;
    return ret;
}

int coinChange(int* coins, int coinsSize, int amount) {
    int *um = calloc(amount + 1, sizeof *um);
    int ret = coinChange_(coins, coinsSize, um, amount);
    free(um);
    return ret;
}