当前位置: 首页 > 知识库问答 >
问题:

您将如何调整我的递归硬币和算法解决方案?

俞涵涤
2023-03-14

我正在研究一个硬币总数问题:

给定一组可用面额和一个目标金额,我想得到总计到该目标金额的组合数。每一种面额我都可以随便拿。

输入:

  • 面额:[1、5、10]

预期产出: 4

说明:我可以对相应的面额进行以下计数:

[10,0,0],[5,1,0],[0,2,0]或[0,0,1]

function func(denomenations, targetSum) {
  let totalCombos = 0;
  function generate(denomsLeft, remainder) {
    if(remainder === 0){
      totalCombos += 1;
      return
    }
    if(remainder - denomsLeft[0] >= 0) {
      generate(denomsLeft, remainder - denomsLeft[0])
    }
    if(remainder - denomsLeft[1] >= 0) {
      denomsLeft.splice(0,1)
      generate(denomsLeft, remainder - denomsLeft[0])
    }
  }
  generate(denomenations, targetSum)
  return totalCombos
}

我确信我的解决方案非常接近,但有些地方有点不对劲。

调用func([1,5,10],10)返回3而不是4。我似乎没有得到5的硬币组合

错误在哪里,我如何修复它?

共有2个答案

仲智
2023-03-14

Trincot对您的代码有什么问题以及如何修复它进行了出色的分析

不过,我想指出,有比问题中的方法和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))
盛骏祥
2023-03-14

您的代码中有一些错误:

>

  • if(余数-denomsleet[1]

    您不应使用splicedenomsleet进行变异,因为这将影响递归搜索的其余部分(也是在回溯之后)的结果。相反,创建一个不包含第一个元素的副本,并传递该副本。

    此外,当您决定不再使用第一个面额时,您不应该从余数中扣除它。因此,结合上一点,您应该:

    generate(denomsLeft.slice(1), remainder)
    

    然后,您还需要进行检查,以查看是否仍有面额剩余:

    if (!denomsLeft.length) return;
    

    这会解决它的。但我也建议:

    因此,这将是生成的代码:

    function func(denomenations, targetSum) {
      let totalCombos = 0;
      function generate(denomsLeft, remainder) {
        if (remainder < 0) return;
        if (remainder === 0){
          totalCombos += 1;
          return
        }
        if (!denomsLeft.length) return;
        generate(denomsLeft, remainder - denomsLeft[0])
        generate(denomsLeft.slice(1), remainder)
      }
      generate(denomenations, targetSum)
      return totalCombos
    }
    
    console.log(func([1,5,10],10)); // 4
    console.log(func([1,2,5],5)); // 4

  •  类似资料:
    • 给定一个值N,如果我们想改变为N美分,并且我们有无限量的S={S1,S2,...,Sm}值的硬币,我们有多少种方法可以改变?硬币的顺序并不重要。不过还有一个额外的限制:你只能用正好是K的硬币换零钱。 例如,对于N=4,k=2和S={1,2,3},有两个解:{2,2},{1,3}。所以输出应该是2。 解决方案: 以上是递归解决方案。但是,我需要有关动态规划解决方案的帮助: 让表示与元素和硬币的总和。

    • 我试图用递归来解决硬币兑换问题,遇到了下面的代码。 问题:给定一些面额的无限硬币,计算它们形成给定数量的方式。 输入: 代码: 我理解代码本身,也理解基本情况,但是我不理解它是如何封装递归/解决方案的。 例如,如果我正在求解,我可以说,因此我可以清楚地“看到”递归。在换硬币的例子中,我无法推断出类似的关系。有人能帮我吗?

    • 尝试为一般硬币更换问题编程一个DP解决方案,该解决方案还可以跟踪使用的硬币。到目前为止,我一直在努力给我所需的最低硬币数量,但不知道如何获得使用了哪些硬币以及使用了多少次。我尝试设置另一个表(布尔值),如果硬币被使用,但这似乎不能正常工作。有什么想法吗?

    • 以人民币的硬币为例,假设硬币数量足够多。要求将一定数额的钱兑换成硬币。要求兑换硬币数量最少。 思路说明: 这是用贪婪算法的典型应用。在本例中用python来实现,主要思想是将货币金额除以某硬币单位,然后去整数,即为该硬币的个数;余数则做为向下循环计算的货币金额。 这个算法的问题在于,得出来的结果不一定是最有结果。比如,硬币单位是[1,4,6],如果将8兑换成硬币,按照硬币数量最少原则,应该兑换成为

    • 我有一个练习: 您将获得不同面额的硬币和总金额。请编写一个函数来计算您需要的最少数量的硬币,以弥补该金额。如果硬币的任何组合都无法弥补该金额,请返回-1 例1: 我还谷歌了一个这样的解决方案: 我知道它是关于DP的,但是,我对它很困惑,比如,的含义是什么,为什么要添加,为什么要添加,为什么要添加1? 有人能用简单的英语指出出路吗?

    • 我试图用递归的方法解决硬币兑换问题。问题是这样的: 你会得到不同面额的硬币和总金额。编写一个函数来计算组成该数量的组合数。 您将获得一个数量和一组硬币。 这是我到目前为止所拥有的: 当我这样做的时候,我没有得到任何接近正确的组合。我认为问题是回报,但我不明白为什么。在这里,我把硬币从数量中减去,每次都加在一起。当它得到0时,它返回1。