3

I'm trying the java coin change problem to enumerate all possible sets of change to be given for n.

My logic follows as such:

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

return coinChanger(++denom)

My code:

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

This outputs just 1 set of all the enumerations:

OUTPUT:

27
0
0
0
RESULT CHANGE PERMUTATIONS LIST: [27]

Questions:

I'm struggling to figure out how move to the next denomination once one of them finishes... I know you're supposed to move to the next index in the denomination array... but then that just adds the next coin... how do I make it add the next largest coin, then recursively drop to the next coin... all the way through all 4 coins?

Thanks!

*EDIT**

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

DESIRED OUTPUT: List of Lists... 27 cents:

LIST{ [1, 0, 0, 2], [0, 2, 1, 2], [0, 1, 3, 2]... etc}

user3871
  • 12,432
  • 33
  • 128
  • 268

2 Answers2

6

Simplest solution is to recurse into two variants at each step (if you are not finished):

  1. Continue with the current coin: Add it to the list and recurse.
  2. Switch to the next coin: Increment coin pos and recurse.

Should look like this:

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

If you want to collect the lists, you need to make a copy of the list where a coin is added (instead of removing it after returning from the call).

Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51
  • Ahh, I was close. I was creating a new list in `changeMaker` each call which I was adding the current denomination to... then I'd add that resultDenom array to the resultsList... Btw, isn't putting `coins.remove(coins.size()-1);` after the recursive call to `change(remaining - DENOMINATIONS[pos], coins, pos);` going to make it unreachable? Also, I guess what I was going for listing the total coins out in a List of Lists, so for 52 cents it'd be: `LIST[{2, 0, 0, 2}, {1, 2, 1, 2}, {0, 5, 0, 2}, etc...]`, and not coins in new lists as you've done, `[25, 25, 1, 1], [25, 10, 10, 5, 2]`, etc... – user3871 May 13 '13 at 14:45
  • Oops it won't be unreachable... it is for me because I'm returning a list `return changeMaker(change-=denominations[index], coinsList, index);` after I add the current denomination to the coinsList... Can you explain why you're doing `coins.remove(coins.size() - 1);`, I'm not sure why that's necessary to remove – user3871 May 13 '13 at 15:00
  • That's because I am reusing the same list in the second recursive call. If I wouldn't do this, the case of just going to the next denomination without adding a coin would not be covered. An alternative would be to copy the list before the first recursive call. You could also do a loop for one of the cases (and recurse inside the loop) but a pure recursive version seemed simpler to me. – Stefan Haustein May 13 '13 at 16:15
-1

Your code seems a little convoluted for the problem you're trying to solve

Try implementing this pseudo-code

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

You can easily replace the if statements with hardcoded values with array indices and a for loop, and printing with however you wish to record the values. I hope that helps.

bengoesboom
  • 2,119
  • 2
  • 23
  • 27