タイトル
コインコインの異なる宗派や金額の合計額を考えます。私たちは、合計金額を構成するために必要なコインの最小数を計算するための関数を書くことができます。コインの合計金額のいずれかで構成することができない組み合わせがない場合、-1を返します。
例1
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
例2
输入: coins = [2], amount = 3
输出: -1
思考
- バックトラックDFS
- ピギーバック
- のバック思い出
- 動的プログラミング(O(N ^ 2)空間的複雑さ)
- O(N)スペースの動的プログラミングの複雑
Aコード:後戻り(タイムアウト)
class Solution {
private:
int res;
vector<int> memo;
public:
int coinChange(vector<int>& coins, int amount) {
memo = vector<int>( amount+1, 0 );
return dfs( coins, amount ) ;
}
int dfs( vector<int>& coins, int amount ) {
if ( amount == 0 ) return 0;
if ( amount < 0 ) return -1;
if ( memo[amount] != 0 ) return memo[amount];
int Min = INT_MAX;
for ( auto& coin : coins ) {
int res = dfs( coins, amount-coin );
if ( res >= 0 && res < Min )
Min = res + 1;
}
memo[amount] = ( Min == INT_MAX ? -1 : Min ) ;
return memo[amount];
}
};
コードII:回顧(メモリの)
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> memo( amount+1, 0 );
helper( coins, amount, memo );
return memo[amount];
}
int helper( vector<int>& coins, int remain, vector<int>& memo ) {
if ( remain < 0 ) return -1;
if ( remain == 0 ) return 0;
if ( memo[remain] != 0 ) return memo[remain];
int res = INT_MAX;
for ( auto& coin : coins ) {
int temp = helper( coins, remain - coin, memo );
if ( temp >= 0 )
res = min( res, temp + 1 );
}
memo[remain] = ( res == INT_MAX ? -1 : res );
return memo[remain];
}
};
コードIII:ピギーバック+
class Solution {
private:
int res;
public:
int coinChange(vector<int>& coins, int amount) {
if ( !amount ) return 0;
res = INT_MAX;
sort( coins.rbegin(), coins.rend() );
dfs( coins, 0, amount, 0 );
return res == INT_MAX ? -1 : res;
}
void dfs( vector<int>& coins, int index, int amount, int lens ) {
if ( amount == 0 ) {
res = min( res, lens );
return;
}
if ( index == coins.size() ) return;
for ( int i = amount / coins[index]; i >= 0 && lens+i < res; --i )
dfs( coins, index+1, amount - i * coins[index], lens + i );
return;
}
};
コード4:動的計画 スペース
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<vector<int>> dp( amount+1, vector<int>( coins.size()+1, amount+1 ) );
dp[0][0] = 0;
for ( int i = 0; i <= amount; ++i ) {
for ( int j = 1; j <= coins.size(); ++j ) {
dp[i][j] = dp[i][j-1];
if ( i >= coins[j-1] )
dp[i][j] = min( dp[i][j], dp[i-coins[j-1]][j] + 1 );
}
}
return dp[amount][coins.size()] > amount ? -1 : dp[amount][coins.size()];
}
};
コードV:動的プログラミング スペース
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp( amount+1, amount+1 );
dp[0] = 0;
for ( int i = 1; i <= amount; ++i ) {
for ( auto& coin : coins ) {
if ( i >= coin )
dp[i] = min( dp[i], dp[i-coin] + 1 );
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
};