Coin Change, a Dynamic Programming problem, by LeetCode

Here it is: https://leetcode.com/problems/coin-change/description/

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
Example 1:
Input: coins = [1, 2, 5], amount = 11
Output: 3 
Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3
Output: -1
Note:
You may assume that you have an infinite number of each kind of coin.
Same cues again that this is a DP problem: asking for the fewest number of combinations (not the combinations themselves), exponential in nature if you were to compute all permutations. Now it was not said how large "amount" can be, but assume that it is a reasonable value (say <= 1000000). We can find a solution to this problem in O(amount * len(coins))-time and O(amount)-space using DP.
The idea with DP again is to construct the solution from 0,1,2... all the way to amount. Suppose that you're computing the solution for N. And assume that you have 3 coins C1, C2 and C3 (you can generalize later). To get to N, inevitably you'll have to get to either N-C1, or N-C2 or N-C3. Compute the min out of those, add 1. Keep doing that until you reach amount. That's it! Code is below, cheers, Marcelo.


public class Solution
{
 public int CoinChange(int[] coins, int amount)
 {
  //Base
  if (amount < 0) return -1;
  if (amount == 0) return 0;

  //Induction DP
  int[] minChange = new int[amount + 1];

  for (int i = 1; i <= amount; i++)
  {
   int min = Int32.MaxValue;
   for (int j = 0; j < coins.Length; j++)
    if (i - coins[j] >= 0 && minChange[i - coins[j]] != -1 && minChange[i-coins[j]] + 1 < min)
     min = minChange[i - coins[j]] + 1;
   minChange[i] = (min == Int32.MaxValue) ? -1 : min;
  }

  return minChange[amount];
 }
}

Comments

  1. Classics of DP :) My solution is more verbose because it keeps only 2 rows instead of entire matrix in memory, but the idea is the same.

    class Solution {
    public:
    int coinChange(vector& coins, int amount) {
    vector> d(2, vector(amount+1, amount+1));
    d[0][0] = 0;
    bool prev = 0;
    bool current = 1;
    for (int c = 1; c <= coins.size(); ++c) {
    d[current][0] = 0;
    for (long a = 1; a <= amount; ++a) {
    if (coins[c-1] <= a) {
    d[current][a] = min(1 + d[current][a-coins[c-1]], d[prev][a]);
    } else {
    d[current][a] = d[prev][a];
    }
    }
    prev = !prev;
    current = !current;
    }
    auto min_coins = d[prev][amount];
    return min_coins == amount+1 ? -1 : min_coins;
    }
    };

    ReplyDelete

Post a Comment

Popular posts from this blog

Golang vs. C#: performance characteristics (simple case study)

Claude vs ChatGPT: A Coder's Perspective on LLM Performance

ProjectEuler Problem 719 (some hints, but no spoilers)