Leetcode solution 322: Coin Change

Problem Statement 

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
 

Problem link

Video Tutorial

You can find the detailed video tutorial here

  • Youtube
  • B站

 

Thought Process

This is a classic problem and greedy might be the first thing comes into mind. For example, sort the coins on denomination and always use the largest amount coin. However, the optimal solution might not include the largest denomination.

 

for example , [1, 3, 4] and target value 6. The optimal is two 3s, not [4, 1, 1].

 

It seems we have to list out all the different combinations and find the min value, that leads to a brute fore solution as described here using recursion. It would be an exponential time complexity.

 

We can use a hash map as a lookup to remember for each amount, what would be the min cost. That would significantly reduce the time complexity from exponential to O(S*N) where S is the amount and N is the coins array size. It's not obvious why but once you see the DP solution, you can understand better, it's the same time complexity.

 

Another way is to use dynamic programming because the problem is asking for a single yes/no, extreme value(min, max), building up a lookup table using formula is the coding pattern. We have similar problems, Wild Card Matching, Regular Expression Matching

 

The idea is to build a lookup table for each amount, what's the minimal number of coins needed given current  denomination.

lookup[i] = min(lookup[i], lookup[i - coin value] + 1) given i - coin value >= 0

Solutions

Dynamic Programming

 1 public int coinChangeDP(int[] coins, int amount) {
 2     if (coins == null || coins.length == 0) {
 3         return -1;
 4     }
 5     // lookup contains the min number of coins needed to reach the amount(i.e., index)
 6     int[] lookup = new int[amount + 1];
 7     lookup[0] = 0;
 8 
 9     for (int i = 1; i <= amount; i++) {
10         int min = Integer.MAX_VALUE;
11         for (int coin : coins) {
12             if (i >= coin && lookup[i - coin] != -1) {
13                 min = Math.min(min, lookup[i - coin] + 1);
14             }
15         }
16         lookup[i] = (min == Integer.MAX_VALUE ? -1 : min);
17     }
18 
19     return lookup[amount];
20 }

 

Time Complexity: O(S*N) where S is the amount and N is the coins array size

Space Complexity: O(N) since we used a lookup array

 

References

上一篇:518. Coin Change 2


下一篇:扔鸡蛋问题和找零钱问题