0

I was attempting to solve the coin change problem (https://leetcode.com/problems/coin-change) and have come up with the following recursive approach:

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] min = new int[1];
        min[0] = Integer.MAX_VALUE;
        recur(coins,amount,min,0);
        min[0] = min[0]==Integer.MAX_VALUE?-1:min[0];
        return min[0];
    }
    private void recur(int[] coins,int amount,int[] min,int coinsUsed){
        if(amount==0){
            min[0] = Math.min(min[0],coinsUsed);
            return;
        }
        if(amount<0){
            return;
        }
        for(int i=0;i<coins.length;++i){
            recur(coins,amount-coins[i],min,coinsUsed+1);
        }
    }
}

Currently the time complexity would be O((coins.length)^n). How can I add memoization to improve this?

1 Answers1

0

Usually top-down with memoization gets a bit complicated. A simple way is to use a 2-d array and solve the problem bottom up. Suppose you have n denominations (index from 1 to n) and the sum is S. Let T[n][S] be the minimal number of coins you need to add up to S and v[n] the value of coin n.

You have two choices either you use coin n or you don't. If you don't then T[n][S]=T[n-1][S]. If you do then T[n][S]=1+T[n][S-v[n]] since you don't know which is better then

T[n][S]=min (T[n-1][S],1+T[n][S-v[n]]). This is true for all n therefore we get the recursive formula.

T[i][s]=min(T[i-1][s],1+T[i][s-v[i]])

Now for the boundary conditions

  1. If i=1 then T[1][s]=s for all 0<= s <= S
  2. T[i][0]=0 for 1<= i<= n
int x,y;
int T[n+1][S+1];
//initialization
for(y=0;y<=S;y++)
   T[1][y]=y;
for(x=0;x<=n;x++)
   T[x][0]=0;
//solution
for(x=2;x<=n;x++){
   for(y=0;y<=S;y++){
       if (v[x]>= y )
           T[x][y]=min(T[x-1][y],1+T[x][y-v[x]];
       else
             T[x][y]=T[x-1][y];
    }
}
Hikmat Farhat
  • 552
  • 3
  • 9