LeetCode322コイン宗派組合せ問題
题目描述:あなたは異なる宗派やお金の総量のコイン与えられている 量。あなたはその金額を構成するために必要なコインの最小数を計算する関数を書きます。お金の量は、コインの任意の組み合わせによって構成されたことができない場合は、返します -1
。
この質問は、コインの組み合わせの最小数を見つけるために、コインに状況の無限の数を一定値とコインの額面を与えている質問の意味は、非常に古典的で、組み合わせは戻りません-1。
タイトルを読んだ後、すぐに解決DPを考えました。
一般的に考えられ、その組み合わせの最小数量=各硬貨の金種の量の組み合わせ+ 1の最小数を減算することによって
解決するためのDP漸化式が与えられます:
[量]をカウント=分{[量 - コイン[I]カウント}、0 <= iがn <。
ここでCOUNT【量】量値を必要なコインの最小数の組合せを表し、硬貨は、アレイのコイン金種です。
この式によると、我々は簡単に擬似コードを与えることができます:
coinChange(int型 []コイン、int型の量): [カウントしましょう0、1を ...量+ 1も] 新しい配列 foreachの私は: [i]はカウント = Max.valueを するために I = 0量+に1 : 場合(私を== 0)[カウント0 ] = 0 他: lはなりましょう新しいリスト のためのk = 0 :coins.lengthの 場合はコイン[K]> = - (I 0)(カウント[I-コイン[K] + list.add 1 )。 カウント = getMin(l)は// リットルでゼロより上の最大値を取得し 、リターン [量] = Max.valueを数えますか?- 1 :カウント[量]
ディスカバリーは、具体的には提出後に少なくとも液で少し時間を学ぶために、非常に低い時間ランクを実行します。
第二の溶液は、貪欲再帰溶液に基づいている:
一般的な考え方は、第一の組み合わせのグローバル変数レコード番号をソートし、使用するコインの額面を行うことです。
最大硬貨の金種から出発して、各組み合わせにおける硬貨の最大数が計算され、これが今度は、再帰的計算の数を減らす、組み合わせの数を記録し、グローバル変数が更新さ未満です。
コードは以下の通りであります:
プライベートint型のres = Integer.MAX_VALUEで、 公共INT coinChange(INT []コイン、INT量){ は、Arrays.sort(コイン)。 coinChange(コイン、量、coins.length-1、0); 解像度== Integer.MAX_VALUEのを返しますか?-1:RES。 } // プライベートボイドcoinChange(INT []コイン、INT量、INTのCUR、INT数){ IF(CUR <0) のリターン; //再帰coinChangeの停止が int型I =量/硬貨[CUR]。//ほとんどなし。コインの[CUR] IF(量%のコイン[CUR] == 0){ RES = Math.min(RES、+ Iカウント)。 返します。 } のための(; I> = 0; i--){ IF(カウント+ I + 1> =のRES){ 返します。 } coinChange(コイン、量、コイン[CUR] * I、CUR-1は、+ Iカウント)。 } }