4

I'm currently working on the coin change dynamic-programming question on leetcode -- https://leetcode.com/problems/coin-change/.

Here is the question 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

I tried to implemented a top-down memoization approach, where I keep an array of length amount, where each index represents the minimum amount of coins I can use to make that amount.

Here is my code in Java:

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];

        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;

        int min = coinChange(coins, amount, dp);

        return min == Integer.MAX_VALUE ? -1 : min;
    }

    private int coinChange(int[] coins, int amount, int[] dp) {
        if (amount < 0) {
            return Integer.MAX_VALUE;
        }
        if (amount == 0) {
            return 0;
        }

        if (dp[amount] != Integer.MAX_VALUE) {
            return dp[amount];
        }

        int min = Integer.MAX_VALUE;
        for (int i = 0; i < coins.length; i++) {
            int val = coinChange(coins, amount - coins[i], dp);

            if (val != Integer.MAX_VALUE) {
                min = Math.min(min, val + 1);
            }
        }

        dp[amount] = min;
        return min;
    }
}

I thought this was the correct approach to dynamic-programming for this problem, however I'm getting Time Limit Exceeded on leetcode.

Is this a wrong approach do dynamic programming? If so, can you please explain where it is wrong?

Thank you so much in advance.

Wonjoo Lee
  • 99
  • 3
  • 8
  • You probably should define your specific coin change problem and not assume others know this problem. Also mention what programming language you are using for the code in the question. It looks like Java to me but others may not know that. – ThomasMcLeod Mar 05 '19 at 00:21
  • @ThomasMcLeod Thanks for the suggestion! The link to the problem was already there, but I've included the problem statement in the post as well. I also noted that the solution is in Java. Thanks! – Wonjoo Lee Mar 05 '19 at 00:43
  • I actually have the exact same code and exact same problem – Mohit Shah Aug 30 '19 at 04:11

2 Answers2

2

This is my version of the solution. This is easy to understand as well!

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];

        Arrays.fill(dp, 0);

        int min = coinChange(coins, amount, dp);
        return min;
    }

    private int coinChange(int[] coins, int amount, int[] dp) {
        if (amount < 0) {
            return -1;
        }
        if (amount == 0) {
            return 0;
        }

        if (dp[amount]!=0) {
            return dp[amount];
        }

        int minimum = Integer.MAX_VALUE;
        for (int i = 0; i < coins.length; i++) {
            int val = coinChange(coins, amount - coins[i], dp);

            if (val >= 0 && val < minimum) {
                minimum = val + 1;
            }
        }
        dp[amount] = (minimum == Integer.MAX_VALUE) ? -1 : minimum;
        return dp[amount];
    }
}
executable
  • 180
  • 1
  • 12
  • This returns 2 for input `{ 9, 6, 5, 1 };` and `amount=12`. Should not this be 3? which 2 coins will give me the sum 12? – Arun Gowda Jan 16 '20 at 13:39
  • 2
    @ArunGowda Two 6's will give you 12 as there are infinite number of coins of each type. Also this solution passes all test cases at leetcode as on 18th Jan 2020 at 11:28 am. – executable Jan 18 '20 at 05:58
  • 1
    I later realized the fact that there are infinite supplies of coins. Cheers – Arun Gowda Jan 18 '20 at 07:45
1

Your dp[amount] array will still go for recursion for all those amount for which it does not have solution i.e. if dp[amount] is less than 0, this will return INT_MAX, dp[amount] will INT_MAX. But you are checking that if dp[amount] !=INT_MAX then only return dp[amount] value. That is why TTE.