Skip to content

Latest commit

 

History

History
213 lines (190 loc) · 6.41 KB

322. Coin Change.md

File metadata and controls

213 lines (190 loc) · 6.41 KB

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.

Solution

  • mine
    • Java
      • DFS & Recursion & BackTrack Runtime: 58 ms, faster than 9.66%, Memory Usage: 36.8 MB, less than 99.87% of Java online submissions

        int res = Integer.MAX_VALUE;
        public int coinChange(int[] coins, int amount) {
            if(amount <= 0){
                return 0;
            }
            if (coins == null || coins.length == 0) {
                return -1;
            }
            if (coins.length == 1) {
                return amount % coins[0] == 0 ? amount / coins[0] : -1;
            }
            Arrays.sort(coins);
            dfs(coins, amount, coins.length - 1, 0);
            if (res == Integer.MAX_VALUE) {
                return -1;
            }
            return res;
        }
        
        public void dfs(int[] coins, int amount, int end, int count) {
            if (coins == null || amount < coins[0] || end < 0) {
                return;
            }
            for (int i = end; i >= 0; i--) {
                if (count > res) {
                    return;
                }
                int d = amount / coins[i];
                int m = amount % coins[i];
                if (d > 0) {
                    if (m == 0) {
                        res = Math.min(res, count + d);
                        return;
                    } else if (i == 0) {
                        return;
                    }
                    while (d >= 0) {
                        if (count + d > res) {
                            break;
                        }
                        dfs(coins, m, i - 1, count + d);
                        d--;
                        m += coins[i];
                    }
                }
            }
        }
        
      • DFS & Recursion & BackTrack Optimization Runtime: 2 ms, faster than 99.39%, Memory Usage: 37 MB, less than 99.42% of Java online submissions

        int res = Integer.MAX_VALUE;
        
        public int coinChange(int[] coins, int amount) {
            if (amount <= 0) {
                return 0;
            }
            if (coins == null || coins.length == 0) {
                return -1;
            }
            if (coins.length == 1) {
                return amount % coins[0] == 0 ? amount / coins[0] : -1;
            }
            Arrays.sort(coins);
            dfs(coins, amount, coins.length - 1, 0);
            return res == Integer.MAX_VALUE ? -1 : res;
        }
        
        public void dfs(int[] coins, int amount, int end, int count) {
            if (coins == null || amount < coins[0] || end < 0) {
                return;
            }
            for (int i = amount / coins[end]; i >= 0; i--) {
                int amountLeft = amount - i * coins[end];
                int curCount = count + i;
                if (amountLeft == 0) {
                    res = Math.min(res, curCount);
                    break;
                }
                if (curCount + 1 >= res) {
                    break;
                }
                dfs(coins, amountLeft, end - 1, curCount);
            }
        }
        

  • the most votes

    • solution link in leetcode

    • solution link in leetcode.cn,

    • Recursion & BackTrack Runtime: 2 ms, faster than 99.39%,Memory Usage: 36.5 MB, less than 99.98% of Java online submissions

      int total = Integer.MAX_VALUE;
      public int coinChange(int[] coins, int amount) {
          if (amount == 0) return 0;
          Arrays.sort(coins);
          count(amount, coins.length - 1, coins, 0);
          return total == Integer.MAX_VALUE ? -1 : total;
      }
      
      void count(int amount, int index, int[] coins, int count) {
          if (index < 0 || count >= total - 1) return;
          int c = amount / coins[index];
          for (int i = c; i >= 0; i--) {
              int newCount = count + i;
              int rem = amount - i * coins[index];
      
              if (rem > 0 && newCount < total)
                  count(rem, index - 1, coins, newCount);
              else if (newCount < total)
                  total = newCount;
              else if (newCount >= total - 1)
                  break;
          }
      }
      

  • leetcode
    • Dynamic programming - Top down

      Runtime: 33 ms, faster than 17.98%,Memory Usage: 39.1 MB, less than 62.56% of Java online submissions

      // O(N * L)time O(N)space
      // N = amount,  L= coins.length
      public int coinChange(int[] coins, int amount) {
          if (amount < 1) {
              return 0;
          }
          return coinChange(coins, amount, new int[amount]);
      }
      
      private int coinChange(int[] coins, int rem, int[] count) {
          if (rem < 0) {
              return -1;
          }
          if (rem == 0) {
              return 0;
          }
          if (count[rem - 1] != 0) {
              return count[rem - 1];
          }
          int min = Integer.MAX_VALUE;
          for (int coin : coins) {
              int res = coinChange(coins, rem - coin, count);
              if (res >= 0 && res < min){
                  min = 1 + res;
              }
          }
          count[rem - 1] = (min == Integer.MAX_VALUE) ? -1 : min;
          return count[rem - 1];
      }
      
    • Dynamic programming - Bottom up

      Runtime: 11 ms, faster than 86.24%, Memory Usage: 39 MB, less than 75.89% of Java online submissions

      // O(N * L)time O(N)space
      // N = amount,  L= coins.length
      public int coinChange(int[] coins, int amount) {
          int max = amount + 1;
          int[] dp = new int[amount + 1];
          Arrays.fill(dp, max);
          dp[0] = 0;
          for (int i = 1; i <= amount; i++) {
              for (int j = 0; j < coins.length; j++) {
                  if (coins[j] <= i) {
                      dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
                  }
              }
          }
          return dp[amount] > amount ? -1 : dp[amount];
      }