322. Coin Change

package LeetCode_322

/**
 * 322. Coin Change
 * 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.
 * */
class Solution {
    private var array: IntArray? = null

    fun coinChange(coins: IntArray, amount: Int): Int {
        //init array with amount + 1, then we can use it conveniently
        array = IntArray(amount + 1, { 0 })
        return dfs(coins, amount)
    }

    /*
    * solution: recursion + memorization (Top-Down), Time complexity:O(amount*amount), Space complexity:O(amount+1)
    * */
    private fun dfs(coins: IntArray, target: Int): Int {
        if (target < 0) {
            return -1
        }
        if (target == 0) {
            //match the amount, mean no more coin to add
            return 0
        }
        if (array!![target] != 0) {
            return array!![target]
        }
        var min = Int.MAX_VALUE
        for (coin in coins) {
            val sub = dfs(coins, target - coin)
            if (sub >= 0 && sub < min) {
                //+1, just mean we had used 1 coin
                min = 1 + sub
            }
        }
        array!![target] = if (min == Int.MAX_VALUE) -1 else min
        return array!![target]
    }

    /*
    solution 2: dp (Bottom-Up)
    * */
private fun dp(coins: IntArray, amount: Int): Int {
  val dp = IntArray(amount + 1, { amount + 1 })
  //mean that i can use zero coin to sum up 0
  dp[0] = 0
  for (i in 0..amount) {
   for (coin in coins) {
   if (i >= coin) {
   //dp[i - coin] + 1, i used that coin
   dp[i] = Math.min(dp[i], dp[i - coin] + 1)
   }
   }
  }
  return if (dp[amount] > amount) -1 else dp[amount]
}
原文地址:https://www.cnblogs.com/johnnyzhao/p/13024854.html