Alger logo
𝔸𝕝𝕘𝕖𝕣
About

Coin Change

/**
 * @params {Array} coins
 * @params {Number} amount
 */
export const change = (coins, amount) => {
  // Create and initialize the storage
  const combinations = new Array(amount + 1).fill(0)
  combinations[0] = 1
  // Determine the direction of smallest sub-problem
  for (let i = 0; i < coins.length; i++) {
    // Travel and fill the combinations array
    for (let j = coins[i]; j < combinations.length; j++) {
      combinations[j] += combinations[j - coins[i]]
    }
  }
  return combinations[amount]
}
/**
 * @params {Array} coins
 * @params {Number} amount
 */
export const coinChangeMin = (coins, amount) => {
  const map = { 0: 1 }
  for (let i = 1; i <= amount; i++) {
    let min = Infinity
    for (const coin of coins) {
      if (i < coin) continue
      min = Math.min(min, 1 + map[i - coin])
    }
    map[i] = min
  }
  return map[amount] === Infinity ? -1 : map[amount] - 1
}
About this Algorithm

Problem Statement

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.

Approach

Let the dp[i] be the length of the coin change of prefix N[1..i]. Our answer is dp[N]. We fill dp[0] as 1 because there is only one way to get 0 coins (We pick no coins).

Now let's try calculate dp[i] for any i. dp[0..i] will store each sub problems from 0 to N. That's why the answer will be dp[N]. First, we need to iterate each coin types to pick them one-by-one. Then we iterate the sub problems from current coin that we pick before to N cents. That's why we must make dp table with N columns.

This is the codes for the Coin Change algorithm:

    for coin_val in S:
        for i in range(coin_val, n + 1):
            dp[i] += dp[i - coin_val]

In the second iteration, for every cent that can be exchanged, we take it by subtracting the i-th column by the value of the coin we take and adding it into the current column. So dp[i] will store the current sub problem.

Time Complexity

O(N * S) in any case

Space Complexity

O(N) - simple implementation. We only need 1D array to store the answer.

Example

Let's say we have 3 coin types [1,2,3] and we want to change for 7 cents. So we will define our table like this.

[1, 0, 0, 0, 0, 0, 0, 0]

0th column will store 1 since there is only one way to get 0 cents.

  • For the first iteration we take a coin that has a value of 1. Then for all sub problems, there is only one way to make change. For 7 cents, the only way is {1,1,1,1,1,1,1}. On the final iteration, our table be like:
[1, 1, 1, 1, 1, 1, 1, 1]
  • For the second iteration, we take a coin that has a value of 2. From here, all sub problems that can be divided by 2 will store another new way to make change. So, when the iteration stopped at 2nd column it will be like dp[2] += dp[0]. We know that dp[0] stored a value of 1. Thus, dp[2] will store the value of 1 + 1 = 2. From here we know that for 2 cents, there are 2 ways {1,1} and {2}. And this operation will continue. Now our table be like:
[1, 1, 2, 2, 3, 3, 4, 4]

4 ways to make 7 cents using value of 1 and 2. {{1,1,1,1,1,1,1}, {1,1,1,1,1,2}, {1,1,1,2,2}, {1,2,2,2}}

  • For the final iteration (3rd iteration), we take a coin that has a value of 3. Like before, now all the columns that can be divided by 3 will store another new way. And the final result will be like:
[1, 1, 2, 3, 4, 5, 7, 8]

So the final answer is 8. 8 ways to make change of 7 cents using all coin types. {{1,1,1,1,1,1,1}, {1,1,1,1,1,2}, {1,1,1,2,2}, {1,2,2,2}, {1,1,1,1,3}, {1,3,3}, {2,2,3}, {1,1,2,3}}

Code Implementation Link

Python

Video Explanation

Total Unique Ways To Make Change by Back To Back SWE

Algerlogo

© Alger 2022

About us

We are a group of programmers helping each other build new things, whether it be writing complex encryption programs, or simple ciphers. Our goal is to work together to document and model beautiful, helpful and interesting algorithms using code. We are an open-source community - anyone can contribute. We check each other's work, communicate and collaborate to solve problems. We strive to be welcoming, respectful, yet make sure that our code follows the latest programming guidelines.