日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

322. Coin Change

發布時間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 322. Coin Change 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

322. Coin Change

1. 題目描述
題目鏈接

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
Example 1:
Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3
Output: -1
Note:
You may assume that you have an infinite number of each kind of coin.

2. 題目分析
硬幣找零問題,經典的動態規劃問題。給定一個金額,和給定幾種面值確定的硬幣,并且硬幣數量無限,找出使用最少的硬幣數來湊齊想要的金額。
人類的的思維,肯定是,一開始使用最大面額的硬幣去算,然后多了就換小一點的面額,少了,就換大一點的面額,直到等于金額,或者發現無法湊齊整數的金額,則結束。但計算機無法像人類這樣智能,可以準確知道少了多少面額,然后搜索是否有相應的硬幣去湊。而是要一個個去試和比較,這樣的話時間復雜度更高,所以我們不采用這種方法。
根據條件找最優解,并且能夠不斷拆分成相同的小問題,所以動態規劃的思想,自上而下分析。比如說 coins = [1, 2, 5], amount = 11,既然我要湊11塊錢,首先我可以選擇面額為1, 2, 5是三種硬幣,那么如果我
>對金額11湊硬幣數

  • 金額:11
選擇面額剩余金額硬幣數
1101
291
561

>對金額10,9,6分別繼續湊硬幣數

  • 金額:10
選擇面額剩余金額硬幣數
192
282
552
  • 金額:9
選擇面額剩余金額硬幣數
182
272
542
  • 金額:6
選擇面額剩余金額硬幣數
152
242
512

>對金額9,8,5分別繼續湊硬幣數
>對金額8,7,4分別繼續湊硬幣數
>對金額5,4,1分別繼續湊硬幣數

直到等于金額,或者發現無法湊齊整數的金額,則結束。
這是自上而下的分析思路,然后從分析過程也發現,很多金額會唄計算多遍,如果9,8,5等等,為了避免不必要的回溯,提高效率,使用空間換時間的方式,使用備忘錄法,自下而上計算前面金額所需要的硬幣數,然后再使用計算好的金額去計算大金額所需要的硬幣數,像這題,我們可以先計算金額為1,2,3,4,10分別所需要的最小硬幣數,那么不就直接可以統計出金額為11所需要的最小硬幣數了嗎?

3. 解決思路

狀態dp[value],表示金額為value時,所需要的最小硬幣數。那么它會等于dp[value-coins[j]]+1(0=<j<=n)
狀態轉移方程:dp[value] = Math.min(dp[value], dp[value-coins[j]]+1);

4. 代碼實現(java)

package com.algorithm.leetcode.dynamicAllocation;/*** Created by 凌 on 2018/12/15.* 描述:322. Coin Change*/ public class CoinChange {public static void main(String[] args) { // int[] coins = {1, 2, 5}; // int amount = 11;int[] coins = {2};int amount = 0;int result = coinChange(coins,amount);System.out.println(result);}public static int coinChange(int[] coins, int amount) {if (coins == null || coins.length==0 ){return -1;}//f(n) = min(f(n) , f(n - coins[i])+1 ) ,//dp[i]=j表示組成i元,最少需要j個硬幣int[] dp = new int[amount+1];//組成1元,2元,,,n元需要的最小硬幣數for (int value = 1; value <= amount; value++) {//這里必須設置為Integer.MAX_VALUE-1,而不是Integer.MAX_VALUE,因為后面有dp[i - coins[j]] + 1的操作,// 如果為MAX_VALUE,+1則為負數最小值dp[value] = Integer.MAX_VALUE -1;//遍歷所有價值的硬幣,找到符合組合的硬幣for (int j = 0; j < coins.length; j++) {if (value >= coins[j]){dp[value] = Math.min(dp[value], dp[value-coins[j]]+1);}}}return dp[amount] == Integer.MAX_VALUE-1 ? -1 : dp[amount];} }

5. 拓展,求最大硬幣數
分析方法同求最小硬幣數。

狀態dp[value],表示金額為value時,所需要的最大硬幣數。那么它會等于dp[value-coins[j]]+1(0=<j<=n)
狀態轉移方程:dp[value] = Math.max(dp[value], dp[value-coins[j]]+1);

/*** 求最大硬幣數* @param coins* @param amount* @return*/public static int moreCoins(int[]coins,int amount){if (coins==null || coins.length==0 || amount<0){return -1;}//必須注意amount == 0這種特殊情況,因為最后dp[amount] == 0 是直接返回-1,所以需要提前特殊處理if (amount == 0){return 0;}//dp[i]=j表示組成i元,最多需要j個硬幣int[] dp=new int[amount+1];for (int i = 1; i <= amount; i++) { // dp[i]=Integer.MIN_VALUE+1;for (int j = 0; j < coins.length; ++j) {if (coins[j] <= i) {dp[i] = Math.max(dp[i], dp[i - coins[j]] + 1);}}}return dp[amount] == 0 ? -1 : dp[amount];} ```

總結

以上是生活随笔為你收集整理的322. Coin Change的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。