Home > database >  Finite Coins - using recursion
Finite Coins - using recursion

Time:11-15

Given 1 coin from multiple denominations (E.G. a 1 coin, 5 coin, 16 coin), and a sum, return true or false determining if the sum can be made.

boolean go(int[] coins, int goal) 
{
  //Will set each time, but shouldn't matter as toggle is at bottom
  boolean ans = false;
   
  //loop running in recursion till founds ans
   
  //Really bad time complexity lol
  for (int i = 0; i < coins.length && (!ans); i  ) {
    if ((goal - coins[i] == 0) || goal == 0) {
      return true;
    }
     
    if (goal > coins[i]) {
      int[] red = new int[coins.length - 1];
      //it necessary because making list with one less
      int it = 0;
      //Setting new list to avoid runtime
      for(int x = 0; x < coins.length; x  ){
        if(!(i == x)){
          red[it] = coins[i];
          it  = 1;
        }
      }
      //Run with new list
      ans = go(red, goal - coins[i]);
    }
  }
  return ans;
}

This is my code so far. I have made it recursive, yet one of the test cases returns true when it should not. The test case in particular is [111, 1, 2, 3, 9, 11, 20, 30], with the goal doing 8; This should return false (as it cannot add up to 8), but in this case, returns true.

Other test cases work fine, so I believe my code has some sort of an exception.

I have tried to move the base case upward, and make a reverse variation...

boolean go(int[] coins, int goal) 
{
  boolean ans = false;
  if(goal == 0){
    return true;
  }else if(goal < 0){
    return false;
  }
  for (int i = 0; i < coins.length && (!ans); i  ) {
    if (goal >= coins[i]) {
      int[] red = new int[coins.length - 1];
      int it = 0;
      for(int x = 0; x < coins.length; x  ){
        if(!(i == x)){
          red[it] = coins[i];
          it  = 1;
        }
      }
      ans = go(red, goal - coins[i]);
    }
  }
  return ans;
}

is what I've tried, but the base case doesn't seem to affect anything

CodePudding user response:

The bug is in your copying of the coins array: red[it] = coins[i] should really be red[it] = coins[x]...

For time complexity, you don't really have to do a loop inside the method. Each denomination is either part of the sum or not, so you can always remove the first denomination and test with and without it:

boolean go(int[] coins, int goal)  {
    if(goal == 0)
        return true;
    else if(coins.length == 0 || goal < 0)
        return false;
    else {
        int[] tailOfCoins = Arrays.copyOfRange(coins, 1, coins.length);
        return go(tailOfCoins, goal) || go(tailOfCoins, goal - coins[0]);
    }
}
  • Related