[Swift]LeetCode518. 零钱兑换 II | Coin Change 2
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10397402.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin.
Example 1:
Input: amount = 5, coins = [1, 2, 5] Output: 4 Explanation: there are four ways to make up the amount: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1
Example 2:
Input: amount = 3, coins = [2] Output: 0 Explanation: the amount of 3 cannot be made up just with coins of 2.
Example 3:
Input: amount = 10, coins = [10] Output: 1
Note:
You can assume that
- 0 <= amount <= 5000
- 1 <= coin <= 5000
- the number of coins is less than 500
- the answer is guaranteed to fit into signed 32-bit integer
给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
示例 1:
输入: amount = 5, coins = [1, 2, 5] 输出: 4 解释: 有四种方式可以凑成总金额: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1
示例 2:
输入: amount = 3, coins = [2] 输出: 0 解释: 只用面额2的硬币不能凑成总金额3。
示例 3:
输入: amount = 10, coins = [10] 输出: 1
注意:
你可以假设:
- 0 <= amount (总金额) <= 5000
- 1 <= coin (硬币面额) <= 5000
- 硬币种类不超过 500 种
- 结果符合 32 位符号整数
52ms
1 class Solution { 2 func change(_ amount: Int, _ coins: [Int]) -> Int { 3 var memo = Array(repeating: 0, count: amount + 1) 4 memo[0] = 1 5 6 var coins = coins.sorted() 7 8 for coin in coins where coin <= amount { 9 for higherAmount in coin...amount { 10 memo[higherAmount] += memo[higherAmount - coin] 11 } 12 } 13 14 return memo[amount] 15 } 16 }
184ms
1 class Solution { 2 var cache: [Int: Int] = [:] 3 func change(_ amount: Int, _ coins: [Int]) -> Int { 4 return helper(amount, 0, coins.sorted(by: >)) 5 } 6 7 private func helper(_ amount: Int, _ index: Int, _ coins: [Int]) -> Int { 8 if amount == 0 { 9 return 1 10 } 11 if index >= coins.count { return 0 } 12 if let some = cache[5000 * index + amount] { 13 return some 14 } 15 16 var res = 0 17 for i in index..<coins.count { 18 let coin = coins[i] 19 if coin <= amount { 20 res += helper(amount - coin, i, coins) 21 } 22 } 23 cache[5000 * index + amount] = res 24 return res 25 } 26 }
316ms
1 class Solution { 2 func change(_ amount: Int, _ coins: [Int]) -> Int { 3 var row = [1] 4 row.append(contentsOf: [Int](repeating: 0, count: amount)) 5 var dp = [[Int]](repeating: row, count: coins.count + 1) 6 // i: number of coins, the last index in this range is i - 1 7 guard 1 <= coins.count else { 8 return dp[coins.count][amount] 9 } 10 for i in 1...coins.count { 11 guard 1 <= amount else { 12 continue 13 } 14 for j in 1...amount { 15 dp[i][j] = dp[i - 1][j] + (j < coins[i - 1] ? 0 : dp[i][j - coins[i - 1]]) 16 } 17 } 18 return dp[coins.count][amount] 19 } 20 }
332ms
1 class Solution { 2 func change(_ amount: Int, _ coins: [Int]) -> Int { 3 let a = amount + 1 4 let c = coins.count + 1 5 6 var dp = [[Int]](repeating: [Int](repeating: 0, count: c), count: a) 7 8 for j in 0..<c { 9 dp[0][j] = 1 10 } 11 12 for i in 1..<a { 13 for j in 1..<c { 14 if coins[j - 1] <= i { 15 dp[i][j] = dp[i][j - 1] + dp[i - coins[j - 1]][j] 16 } else { 17 dp[i][j] = dp[i][j - 1] 18 } 19 } 20 } 21 22 return dp[a - 1][c - 1] 23 } 24 }