零錢兌換(Python and C++解法)


題目:

給定不同面額的硬幣 coins 和一個總金額 amount。編寫一個函數來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。

示例 1:

輸入: coins = [1, 2, 5], amount = 11
輸出: 3
解釋: 11 = 5 + 5 + 1
示例 2:

輸入: coins = [2], amount = 3
輸出: -1

說明:你可以認為每種硬幣的數量是無限的。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/coin-change

思路:

  采用動態規划思路。

  定義狀態:dp[i] 表示當目標金額為 i 時, 至少需要dp[i]枚硬幣。

  狀態轉移:從當前目標金額中減去不同硬幣的面額,當前目標金額會減少,所需硬幣數量會增加。

Python解法:

 1 class Solution:  2     def coinChange(self, coins: List[int], amount: int) -> int:  3         dp = {}  4         dp[0] = 0  # 目標金額為0時,所需硬幣數量為0
 5         for i in range(1, amount+1):  # 初始化數組
 6             dp[i] = amount+1
 7 
 8         for i in range(1, amount+1):  9             for j in range(len(coins)):  # 每拼湊成一定金額,都來自某種面值硬幣
10                 if coins[j] <= i: # 如果當前硬幣的面額可以湊 11                     dp[i] = min(dp[i], dp[i-coins[j]]+1)  # 狀態轉移方程:dp[i] = min{dp[i-coins[j]]}+1
12         # 如果dp[amount]的數值沒有更新,說明不滿足coins[j] <= i,湊不出結果
13         if dp[amount] == amount+1: return -1
14         else:   return dp[amount]

C++解法:

 1 class Solution {  2 public:  3     int coinChange(vector<int>& coins, int amount) {  4       if(amount < 0)  5         return -1;  6       // 定義狀態:dp[i]表示當前金額為i時至少需要dp[i]個硬幣
 7       vector<int> dp(amount+1, amount+1);  // 由於將dp[0]包含進去了,所以共有amount+1個元素,並且dp元素的最大值都不會大於amount+1
 8       dp[0] = 0;  9       for(int i = 1; i < dp.size(); i++) { 10         for(auto coin = coins.begin(); coin != coins.end(); coin++) { 11           if(i - (*coin) < 0) 12             continue;  // 由於coins的元素不一定是有序的,所以后面可能會出現符合要求的硬幣
13           dp[i] = min(dp[i], dp[i-(*coin)]+1); 14  } 15  } 16       if(dp[amount] == amount + 1) 17         return -1; 18       else
19         return dp[amount]; 20  } 21 };


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM