1. 程式人生 > >leetcode | 322. Coin Change

leetcode | 322. Coin Change

題目

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.

思路與解法

這道題目可以採用動態規劃來解決,思路比較直觀,定義dp[i]表示總額為i時所需的最少硬幣數目。則狀態轉移方程為:

// j為coins切片元素的下標
if i >= coins[
j] { dp[i] = min(dp[i], dp[i-coins[j]] + 1) }

程式碼實現

const INT_MAX = int(^uint(0) >> 1)
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}
func coinChange(coins []int, amount int) int {
	dp := make([]int, amount + 1)
	for i:=1; i<=amount; i++ {
        dp[
i] = INT_MAX for j:=0; j<len(coins); j++ { if i >= coins[j] && uint(dp[i-coins[j]]) < uint(INT_MAX) { dp[i] = min(dp[i], dp[i-coins[j]] + 1) } } } if uint(dp[amount]) >= uint(INT_MAX) { return -1 } return dp[amount] }

遇到的問題

由於定義的INT_MAX為int範圍內的最大整數值,所以當其加1時就會造成溢位,所以在判斷i>=coins[j]時增加判斷uint(dp[i-coins[j]]) < uint(INT_MAX)檢視dp[i-coins[j]]是否被更新為更少的硬幣數目,否則不必更新dp[i]。程式碼最後,通過判斷dp[amount]INT_MAX無符號數的數值大小即可判斷是否存在一種組合。