Search code examples
javaalgorithmdynamic-programming

space optimized solution for coin change


Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter.

For example, for N = 4 and S = {1,2,3}, there are four solutions: {1,1,1,1},{1,1,2},{2,2},{1,3}. So output should be 4. For N = 10 and S = {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5.

I found the 3 approaches HERE. But not able to understand the space optimized dynamic programming approach where only a single dimensional array table[] is used.

int count( int S[], int m, int n )
{
    // table[i] will be storing the number of solutions for
    // value i. We need n+1 rows as the table is consturcted
    // in bottom up manner using the base case (n = 0)
    int table[n+1];

    // Initialize all table values as 0
    memset(table, 0, sizeof(table));

    // Base case (If given value is 0)
    table[0] = 1;

    // Pick all coins one by one and update the table[] values
    // after the index greater than or equal to the value of the
    // picked coin
    for(int i=0; i<m; i++)
        for(int j=S[i]; j<=n; j++)
            table[j] += table[j-S[i]];

    return table[n];
}

Solution

  • First note that table[i] is number of ways for coin change when N=i.

    Given Algorithm fills this array (table[]) as per given set of coin (S[]). Initially all values in table[] are initialized to 0. And table[0] set to 0 (this is base case N=0).

    Each coin adds up values in table[] in following manner.

    For coin of value X, following are updates to table[] -

    1. table[X] = table[X] + 1

      This is easy to understand. Specifically this adds solution {X}.

    2. for all Y > X

      table[Y] = table[Y] + table[Y-X]

      This is tricky to understand. Take example X = 3, and consider case for Y = 4.

      4 = 3 + 1 i.e. 4 can be obtained by combining 3 and 1. And by definition number of ways to get 1 are table[1]. So that many ways are added to table[4]. Thats why above expression uses table[Y-X].

    Following line in your algorithm represents the same (above two steps) -

    table[j] += table[j-S[i]];  
    

    At the end of algorithm, table[n] contains solution for n.