トピック住所:
https://leetcode.com/problems/coin-change-2/
ナップザック問題。ボリュームを考えます
各項目の体積と
、それぞれがそれぞれの記事の無限の数を持っています。彼は、組み合わせの総数のボリュームをいっぱいに尋ねました。平均詰め、非負の整数があります
メイク
、そうするときの体積
あり
組み合わせ、物品の種類ごとの、すなわち数れます
。
基本的な考え方は、動的計画です。セットアップ
フロントを表します
のぬいぐるみの記事
組み合わせの数のボリューム。:だから、非常に多くの組み合わせは、2つのカテゴリに分けることができる
項目を除く、1
、合計
の組み合わせで、
2、含有する物品
、合計
の組み合わせ。
組み合わせの総数は、2の合計です。各列の更新に左から右へ、上から下の行への更新の更新順序、。コードは以下の通りであります:
public class Solution {
public int change(int amount, int[] coins) {
if (amount == 0) {
return 1;
}
if (coins == null || coins.length == 0) {
return 0;
}
int[][] dp = new int[coins.length][amount + 1];
for (int j = 0; j <= amount; j += coins[0]) {
dp[0][j] = 1;
}
for (int i = 1; i < coins.length; i++) {
for (int j = 0; j <= amount; j++) {
dp[i][j] = dp[i - 1][j];
if (j >= coins[i]) {
dp[i][j] += dp[i][j - coins[i]];
}
}
}
return dp[coins.length - 1][amount];
}
}
時間と空間の複雑さ 、 、総体積です。
最適化のスペースを考えてみましょう。各アップデートそのノート 、我々は唯一のすぐ上の行の要素を使用し、銀行の要素を残しました。だから、左から右にそれぞれの行を更新し、更新をスクロールラインに期待しています。コードは以下の通りであります:
public class Solution {
public int change(int amount, int[] coins) {
if (amount == 0) {
return 1;
}
if (coins == null || coins.length == 0) {
return 0;
}
int[] dp = new int[amount + 1];
for (int j = 0; j <= amount; j += coins[0]) {
dp[j] = 1;
}
for (int i = 1; i < coins.length; i++) {
for (int j = coins[i]; j <= amount; j++) {
dp[j] += dp[j - coins[i]];
}
}
return dp[amount];
}
}
同じ時間の複雑さ、スペース 。