Trincot дал превосходный анализ того, что не так с вашим кодом и как его исправить.
Я хотел бы отметить, однако, что существуют более простые методы, чем метод в вопросе и в очистке Трино.
Вот как я могу это сделать:
const coinCount = (denoms, target) =>
target == 0
? 1
: denoms.length == 0 || target < 0
? 0
: // else
coinCount (denoms, target - denoms[0]) + coinCount (denoms.slice (1), target)
console .log (coinCount ([1, 5, 10], 10))
console .log (coinCount ([1, 5, 10, 25], 100))
Мы проверяем, является ли цель 0
. Если это так, мы возвращаем 1
. Если это кажется удивительным, давайте вспомним, что означает один из способов достижения нулевого значения: мы вообще не возвращаем монет!
Если цель не равна нулю и у нас не осталось деноминаций, или если наша цель отрицательна, комбинации монет недоступны, и мы возвращаем 0
.
Наконец, мы можем сделать выбор. Мы либо используем монету первого достоинства, либо нет. Если мы это сделаем, то мы вернемся с тем же набором конфессий, и общая сумма меньше стоимости этого номинала. Если мы этого не сделаем, мы не сможем использовать его позже, поэтому мы вернемся к оставшимся деноминациям и текущему итогу. Добавление значений, возвращаемых этими двумя вариантами, дает нам общее количество.
Мы можем видеть, что рекурсия является надежной, поскольку каждый рекурсивный шаг либо уменьшает общее количество, которое мы ищем (и, следовательно, в конечном итоге мы получим число не больше нуля) или это уменьшает количество конфессий (и, следовательно, мы в конечном итоге достигнем нуля). В любом случае, мы в конечном итоге попадем в один из наших базовых вариантов.
Используя деструктуризацию, мы могли бы выбрать вариант вместо этого:
const coinCount = ([denom = undefined, ...denoms], target) =>
target == 0
? 1
: denom == undefined || target < 0
? 0
: coinCount ([denom, ...denoms], target - denom) + coinCount (denoms, target)
В некотором смысле мне больше нравится этот вариант, но любой из них кажется более чистым express фундаментальная рекурсия в проблеме.
Я думаю, что любой вариант этой техники в целом проще, тем более что оригинал зависит от побочных эффектов во внутренней функции generate
. Эта версия является чистой функцией и использует только одно выражение.