518. Coin Change II
題目網址:https://leetcode.cn/problems/coin-change-ii/
題意:給一整數 array
coins表示不同面額的硬幣, 和一整數amount表示總金額。返回可以湊成
amount的硬幣組合數。如果任何硬幣組合都無法湊出總金額, 則返回0。假設每一種面額的硬幣有無限個。
題目保證結果符合 32-bit 有號整數。

Solution 1:
想法:利用 DP
1. 定義狀態:
- 首先, 會在
coins前先加上一個0, 代表什麼元素都沒有的狀態dp[i][j]:前i種硬幣湊齊金額j的組合數2. 得到轉移方程:
coins[i]有「選 or 不選」兩種可能:
rods[i]不選, 則dp[i][j] = dp[i - 1][j]rods[i]要選, 則dp[i][j] = dp[i][j - coins[i]](每一種面額可無限取, 故為i而非i - 1)3. 初始化:
dp[0][0]:當沒有任何硬幣時, 湊齊金額0的組合數為1(什麼都不選也是一種方案)
➔dp[0][0] = 1dp[i][0]:當amount = 0時, 前i種硬幣湊齊金額j的組合數為1(什麼都不選也是一種方案), 其中1 ≤ i ≤ n
➔dp[i][0] = 1dp[0][j]:當沒有任何硬幣時, 湊齊金額j的組合數為0, 其中1 ≤ j ≤ amount
➔dp[0][j] = 0
class Solution { |
- time:$O(n \cdot amount)$ ➔ for loop, 其中
n是硬幣種類 - space:$O(n \cdot amount)$ ➔
dp
Solution 2:
想法:改進 Solution 1, 因為
dp[i][j]只會用到上一列的狀態, 故只需記住上一列的狀態即可
class Solution { |
- time:$O(n \cdot amount)$ ➔ for loop, 其中
n是硬幣種類 - space:$O(amount)$ ➔
dp,prevRow
延伸問題:
for loop 內、外層能否對調?
不能, 因為這裡定義的 subproblem 是「選擇第
i種硬幣時, 湊齊金額j的方案(組合數)」。如果對調了, 則 subproblem 就會變成「對於金額j, 選擇硬幣的方案(排列數)」e.g.
amount = 3,coins = [1, 2]- 內、外層對調後, 會有 1 + 2、2 + 1 這兩種方案
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論