【Leetcode解題】322. Coin Change
題目
- 題目連結
- 目標函式 :
coinChange(coins, amount)- Input :
coins: List[int]、amount: int - Output :
int
- Input :
解題概念
- 題意 : 給定一整數陣列
coins代表不同面額的硬幣,並且amount代表總金額- 回傳組成
amount所需的最少硬幣數量 - 若該金額不能由任何硬幣組成,則回傳
-1
- 回傳組成
我的寫法
- 想法 :
- 先將
coins升序排序 - 對
coins反轉並使用 for 迴圈- 若
amount可以除以coins[i],則更新cnt與amount - 當面對
coins[i] == 1時,再做特殊處理
- 若
- 先將
- 程式碼 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def coinChange(self, coins, amount):
coins.sort()
if not amount: return 0
cnt = 0
for coin in coins[::-1]:
if coin == 1:
cnt += amount
amount = 0
break
if amount >= coin:
cnt += amount // coin
amount = amount % coin
return cnt if amount == 0 else -1 - 成效 :
- Time Complexity : Wrong Answer
- 發現問題 : 這種計算方式並不是最佳解
- 如果遇到
coins = [1, 2, 8, 9]、amount = 16時 :- 我的算法會變成
9 + 2 + 2 + 2 + 1 = 16(回傳5) - 但最佳解應為
8 + 8 = 16(回傳2)
- 我的算法會變成
- 如果遇到
解答 or 其他優秀寫法 - Dynamic Programming
- 想法 : 應該使用 Dynamic Programming
- 使用
dp[0]~dp[amount]去紀錄從0到amount的最佳解 - 然後使用雙重迴圈 : 先針對每個可能
amount的值i,再針對每個coin - 若
i比coin大,即更新dp[i](決定計不計算coin,再取較小值min(dp[i], dp[i - coin] + 1)) - 若最後發現
dp[amount] == max_value,代表amount無解,則回傳-1
- 使用
- 程式碼 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14def coinChange(self, coins, amount):
max_value = amount + 1
dp = [max_value] * max_value
dp[0] = 0
for i in xrange(1, max_value):
for coin in coins:
if i >= coin:
dp[i] = min(dp[i], dp[i - coin] + 1)
if dp[amount] == max_value:
return -1
return dp[amount] - 成效 :
- Time Complexity : $O(n\times \text{amount})$
- Runtime: 714 ms (faster than 82.91%)
- Memory Usage: 13.5 MB (more than 98.52%)
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Robin's Tech Blog!


