Java递归硬币更改尝试

Java递归硬币更改尝试,java,algorithm,coin-change,Java,Algorithm,Coin Change,我正在尝试java硬币兑换问题,以列举n的所有可能的兑换集 我的逻辑如下: while n >= denom m { array[]+= denom m n-= denom m } list.add[array[]] return coinChanger(++denom) 我的代码: public List<Integer> makeChange(int change) { int[] denominations; denominations = new

我正在尝试java硬币兑换问题,以列举n的所有可能的兑换集

我的逻辑如下:

while n >= denom m {
array[]+= denom m
n-= denom m
}
list.add[array[]]

return coinChanger(++denom)
我的代码:

public List<Integer> makeChange(int change) {

    int[] denominations;
    denominations = new int[]{1, 5, 10, 25};

    return changeMaker(change, denominations, 0);
}

public List<Integer> changeMaker(int change, int[] denominations, int index) {
    List<Integer> resultsList = new ArrayList<Integer>();
    int[] resultDenom;
    resultDenom = new int[4];

    if (change <= 1) {
        return resultsList;
    }

    while (change >= denominations[index]) {
        resultDenom[index] += denominations[index];
        System.out.println("ResultsDenom: " + resultDenom[index]);
        change -= denominations[index];
    }
    resultsList.add(resultDenom[index]);

    for (int val : resultDenom) {
        System.out.println(val);
    }


    if (change > denominations[index]) {    
        return changeMaker(change-=denominations[index], denominations, ++index);       

    }
    return resultsList;
}
问题:

27
0
0
0
RESULT CHANGE PERMUTATIONS LIST: [27]
我正在努力想,一旦其中一个面额完成后,如何转移到下一个面额。。。我知道你应该移动到面额数组中的下一个索引。。。但这只是增加了下一个硬币。。。我如何让它添加下一个最大的硬币,然后递归下降到下一个硬币。。。一直到4枚硬币

谢谢

*编辑**

public List<Integer> makeChange(int change) {

    int[] denominations;
    denominations = new int[]{25, 10, 5, 1};

    return changeMaker(change, denominations, 0);
}

public List<Integer> changeMaker(int change, int[] denominations, int index) {
    List<Integer> resultsList = new ArrayList<Integer>();
    int[] resultDenom;
    resultDenom = new int[4];

    if (change <= 1) {
        return resultsList;
    }

    if (index > 3) { 
        return resultsList;
    }
    //if 27 >= 25
    if (change >= denominations[index]) {   

        //[+25, 0, 0, 0]
        resultDenom[index] += denominations[index];

        //{  LIST  } <--- [25, 0, 0, 0]
                //List now contains { [25, 0, 0, 0], }, still need all other permutations
        resultsList.add(resultDenom[index]);

        //27 - 25, 
        return changeMaker(change-=denominations[index], denominations, ++index);       

    }
    return resultsList;
}
public List makeChange(int-change){
int[]面额;
面额=新整数【】{25,10,5,1};
返回兑换商(兑换,面额,0);
}
公共列表修改器(int change,int[]面额,int索引){
List resultsList=new ArrayList();
int[]resultDenom;
resultDenom=newint[4];
如果(更改3){
返回结果列表;
}
//如果27>=25
如果(更改>=面额[索引]{
//[+25, 0, 0, 0]
resultDenom[索引]+=面额[索引];

//{LIST}对于您试图解决的问题,您的代码似乎有点复杂

尝试实现这个伪代码

  getChange(int totalCents)
  {
      if (totalCents > 25)
      {
         print "25";
         getChange(totalCents - 25);
      } 
      else (totalCents > 10)
      {
         // same for 10
      }
      else (totalCents > 5)
      {
         // same for 5
      }
      else
      {
         // print out number left as pennies
      }
  }

您可以轻松地将if语句替换为带有数组索引和for循环的硬编码值,并以您希望记录值的方式打印。我希望这会有所帮助。

最简单的解决方案是在每一步递归为两个变量(如果未完成):

  • 继续使用当前硬币:将其添加到列表并递归
  • 切换到下一个硬币:增加硬币位置并递归
  • 应该是这样的:

    public class Coins {
      static final int[] DENOMINATIONS = {25, 10, 5, 1};
    
      public static void change(int amount) {
        change(amount, new ArrayList<Integer>(), 0);
      }
    
      private static void change(int remaining, List<Integer> coins, int pos) {
        if (remaining == 0) {
          System.out.println(coins);
        } else {
          if (remaining >= DENOMINATIONS[pos]) {
            coins.add(DENOMINATIONS[pos]);
            change(remaining - DENOMINATIONS[pos], coins, pos);
            coins.remove(coins.size() - 1);
          }
          if (pos + 1 < DENOMINATIONS.length) {
            change(remaining, coins, pos + 1);
          }
        }
      }
    }
    
    公共等级硬币{
    静态最终整数[]面额={25,10,5,1};
    公共静态无效更改(整数金额){
    更改(金额,新ArrayList(),0);
    }
    私有静态无效更改(剩余整数、列表硬币、整数pos){
    如果(剩余==0){
    系统输出打印(硬币);
    }否则{
    如果(剩余>=面额[pos]){
    硬币。添加(面额[pos]);
    更改(剩余-面额[pos]、硬币、pos);
    硬币。移除(硬币。大小()-1);
    }
    如果(位置+1<面额长度){
    零钱(剩余、硬币、pos+1);
    }
    }
    }
    }
    

    如果您想收集列表,您需要制作一份添加硬币的列表副本(而不是在从呼叫返回后将其移除)。

    这是您的全部输出吗?其中是
    System.out.println(“ResultsDenom:+resultDenom[index]”)
    ?如果您的输入是
    27
    ,并且您使用上述代码时没有任何更改,则输出不能是您所提供的……这如何完成枚举所有可能的集合?更改
    If()的顺序else
    conditions xD现在你知道暴力的方式了,看看你如何做的更优雅些吧,我很接近了。我在
    changeMaker
    中创建了一个新的列表,我将当前面额添加到每个调用中…然后我会将resultDenom数组添加到resultsList中…顺便说一句,不是在放置
    coins.remove(coins.size()-1)
    在递归调用
    更改(剩余面额[pos],硬币,pos);
    将使其无法访问?此外,我猜我将在列表中列出所有硬币,因此52美分的价格是:
    列表[{2,0,0,2},{1,2,1,2},{0,5,0,2},等等]
    ,而不是像你所做的那样在新列表中的硬币,
    [25,25,1,1],[25,10,10,5,2]
    ,等等……哎呀,它不会遥不可及……对我来说,因为我正在返回一个列表
    返回changeMaker(更改-=面额[index],硬币列表,索引)
    在我将当前面额添加到硬币列表后…您能解释一下为什么要执行
    硬币.移除(硬币.大小()-1);
    ,我不确定为什么需要删除它,因为我在第二次递归调用中重复使用了相同的列表。如果我不这样做,就不会涉及到只转到下一个面额而不添加硬币的情况。另一种方法是在第一次递归调用之前复制列表。您还可以对其中一个进行循环这些情况(并在循环中递归),但纯递归版本对我来说似乎更简单。