在Javascript中实现递归硬币更改功能

时间:2015-09-18 03:27:34

标签: javascript recursion

我完全被一个递归问题阻止了。这是其他人提出的问题,但似乎没有人在JS中询问过我可以看到的内容(对不起,如果我错过了什么!)并且阅读其他答案并没有帮助。

在任何情况下,我都有一个递归程序,它返回所需的最小硬币数量:

function change(amount, coins){
    if (amount == 0){
        return 0;
    } else if (coins.length == 0 && amount > 0){
        return Infinity;
    } else if (coins[0] > amount){
        return change(amount, coins.slice(1));
    } else {
        var loseIt = 0 + change(amount, coins.slice(1));
        var useIt = 1 + change(amount - coins[0], coins);
        return Math.min(loseIt, useIt);
    }
}

change(48, [1, 5, 10, 25, 50])
>>> 6
change(48, [1, 7, 24, 42])
>>> 2 

但是当我尝试将其修改为不仅返回硬币数量而且还返回使用的硬币时,我仍然会超过堆栈调用的最大数量,或者只是在Chrome中崩溃控制台。

答案应该是

change(48, [1, 5, 10, 25, 50])
>>> [6, [25, 10, 10, 1, 1, 1]]
change(48, [1, 7, 24, 42])
>>> [2, [24, 24]] 

这是我的代码:

function change(amount, coins){
    if (amount == 0){
        return [0,[]];
    } else if (coins.length == 0 && amount > 0){
        return [Infinity,[]];
    } else if (coins[0] > amount){
        return change(amount, coins.slice(1));
    } else {
        var loseIt = [change(amount, coins.slice(1))[0], [].concat(change(amount, coins.slice(1))[1])];
        var useIt = [1 + change(amount - coins[0], coins)[0], [coins[0]].concat(change(amount - coins[0], coins)[1])];
        if (useIt[0] > loseIt[0]){
            return loseIt;
        } else {
            return useIt;
        }
    }
}

这个想法是它应该总是返回一个带有硬币计数和硬币数组的数组。我逐步完成了这个功能,它似乎正在返回正确的答案,但它并没有停止运行。

我有一种感觉它依赖于loseIt / useIt定义,但当我测试类似

的东西时
[x[0] + y[0], x[1].concat(y[1])]

其中xy的数组格式类似于我在函数中返回的数组,它似乎一直返回正确的格式。

我正在自学这个东西,所以没有实验室或助教可以帮助我 - 希望有人可以解释我在这里做错了什么!

1 个答案:

答案 0 :(得分:3)

问题

var loseIt = [
    change(amount, coins.slice(1))[0], [].concat(
    change(amount, coins.slice(1))[1])];
var useIt = [1 + 
    change(amount - coins[0], coins)[0], [coins[0]].concat(
    change(amount - coins[0], coins)[1])];

vs working

var loseIt = 0 + change(amount, coins.slice(1));
var useIt = 1 + change(amount - coins[0], coins);

如您所见,change()loseIt的{​​{1}}来电已完成一次。在具有硬币计数的数组版本中,函数useIt使用相同的参数调用两次,但是在这里需要函数返回值的数组元素。

解决方案:

基本上与仅计数版本相同。 change()change()的{​​{1}}来电。稍后您可以使用该阵列进行进一步处理。

loseIt
useIt