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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[Leetcode][第322题][JAVA][零钱兑换][回溯][记忆化搜索][动态规划]

發布時間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leetcode][第322题][JAVA][零钱兑换][回溯][记忆化搜索][动态规划] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】[中等]

【解答思路】

1. 遞歸(超時)
class Solution {int res = Integer.MAX_VALUE;public int coinChange(int[] coins, int amount) {if(coins.length == 0){return -1;}findWay(coins,amount,0);// 如果沒有任何一種硬幣組合能組成總金額,返回 -1。if(res == Integer.MAX_VALUE){return -1;}return res;}public void findWay(int[] coins,int amount,int count){if(amount < 0){return;}if(amount == 0){res = Math.min(res,count);}for(int i = 0;i < coins.length;i++){findWay(coins,amount-coins[i],count+1);}} }
2. 記憶化搜索 自上而下


可以看出在進行遞歸的時候,有很多重復的節點要進行操作,這樣會浪費很多的時間。
使用數組 memo[ ] 來保存節點的值
memo[n]表示錢幣 n+1可以被換取的最少的硬幣數,不能換取就為 -1
findWay 函數的目的是為了找到 amount 數量的零錢可以兌換的最少硬幣數量,返回其值 int

在進行遞歸的時候,memo[n]被復制了,就不用繼續遞歸了,可以直接的調用

class Solution {int[] memo;public int coinChange(int[] coins, int amount) {if(coins.length == 0){return -1;}memo = new int[amount];return findWay(coins,amount);}// memo[n] 表示錢幣n可以被換取的最少的硬幣數,不能換取就為-1// findWay函數的目的是為了找到 amount數量的零錢可以兌換的最少硬幣數量,返回其值intpublic int findWay(int[] coins,int amount){if(amount < 0){return -1;}if(amount == 0){return 0;}// 記憶化的處理,memo[n]用賦予了值,就不用繼續下面的循環// 直接的返回memo[n] 的最優值if(memo[amount-1] != 0){return memo[amount-1];}int min = Integer.MAX_VALUE;for(int i = 0;i < coins.length;i++){int res = findWay(coins,amount-coins[i]);if(res >= 0 && res < min){min = res + 1; // 加1,是為了加上得到res結果的那個步驟中,兌換的一個硬幣}}memo[amount-1] = (min == Integer.MAX_VALUE ? -1 : min);return memo[amount-1];} }
3. 動態規劃 自下而上

時間復雜度:O(N^2) 空間復雜度:O(N)

class Solution {public int coinChange(int[] coins, int amount) {// 自底向上的動態規劃if(coins.length == 0){return -1;}// memo[n]的值: 表示的湊成總金額為n所需的最少的硬幣個數int[] memo = new int[amount+1];// 給memo賦初值,最多的硬幣數就是全部使用面值1的硬幣進行換// amount + 1 是不可能達到的換取數量,于是使用其進行填充Arrays.fill(memo,amount+1);memo[0] = 0;for(int i = 1; i <= amount;i++){for(int j = 0;j < coins.length;j++){if(i - coins[j] >= 0){// memo[i]有兩種實現的方式,// 一種是包含當前的coins[i],那么剩余錢就是 i-coins[i],這種操作要兌換的硬幣數是 memo[i-coins[j]] + 1// 另一種就是不包含,要兌換的硬幣數是memo[i]memo[i] = Math.min(memo[i],memo[i-coins[j]] + 1);}}}return memo[amount] == (amount+1) ? -1 : memo[amount];} }

【總結】

1. 思路總結

回溯法-〉遞歸樹-〉重復子問題-〉備忘錄/動態規劃

2.【數據結構與算法】【算法思想】【聯系與區別】回溯 貪心 動態規劃 分治

轉載鏈接:https://leetcode-cn.com/problems/coin-change/solution/javadi-gui-ji-yi-hua-sou-suo-dong-tai-gui-hua-by-s/

總結

以上是生活随笔為你收集整理的[Leetcode][第322题][JAVA][零钱兑换][回溯][记忆化搜索][动态规划]的全部內容,希望文章能夠幫你解決所遇到的問題。

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