題目描述:給定硬幣面額陣列 coins 和目標金額 amount,求湊成 amount 所需的最少硬幣數,若無法湊成回傳 -1。
解題思路:這是經典的無界背包問題(Unbounded Knapsack)。定義 dp[i] 為湊成金額 i 所需的最少硬幣數。初始化 dp[0] = 0,其餘為無窮大。對每個金額 i,嘗試所有面額 c:若 i >= c,則 dp[i] = min(dp[i], dp[i-c] + 1)。最後若 dp[amount] 仍為無窮大則回傳 -1。
時間複雜度:O(amount × |coins|) — 雙層迴圈。
空間複雜度:O(amount) — DP 陣列大小。
1. Initialize dp[0..amount] = INF, dp[0] = 0
2. For i from 1 to amount:
a. For each coin c in coins:
- If c <= i and dp[i-c] != INF:
dp[i] = min(dp[i], dp[i-c] + 1)
3. Return dp[amount] == INF ? -1 : dp[amount]BFS O(amount × |coins|):視為最短路徑 — 各 amount 為節點,coins 為邊。BFS 逐層找最少硬幣數。複雜度相同。
自頂向下記憶化:帶快取的遞迴。複雜度相同,但迭代自底向上避免函數呼叫開銷。