Problem¶
You are given an integer array coins
representing coins of different denominations and an integer amount
representing a total amount of money.
Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0
.
You may assume that you have an infinite number of each kind of coin.
The answer is guaranteed to fit into a signed 32-bit integer.
Example 1:
Input: amount = 5, coins = [1,2,5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
Example 2:
Input: amount = 3, coins = [2]
Output: 0
Explanation: the amount of 3 cannot be made up just with coins of 2.
Example 3:
Input: amount = 10, coins = [10]
Output: 1
Constraints:
1 <= coins.length <= 300
1 <= coins[i] <= 5000
- All the values of
coins
are unique. 0 <= amount <= 5000
Solve¶
Dynamic programming¶
O(n ** 2)
The ideal start with a update function:
Which lead to:
With every coins, we loop and adding up the total way to reach each amount.
class Solution {
public int change(int amount, int[] coins) {
int[] count = new int[amount + 1];
count[0] = 1;
for (int i : coins) {
for (int c = i; c <= amount; c++) {
count[c] += count[c-i];
}
}
return count[amount];
}
}
The for loop order have an impact on how the Calculation run:
If you instead doing this:
- We have total of way adding coin (that count with all possible different position
1 2 1 != 1 1 2
) to reach that amount
Comparing¶
I also try some more language to help me familiar with other language array too, it quite surprise to see rust and java beat c in runtime.
java
:¶
We have int
array automate initiation as 0
c
:¶
It keep yelling me about how I can’t using int count[amount+1] = {0}
; This just mean I have to use a hard code value to use this feature of the language.
To initiation use a variable size, we instead use memset
.
Also, C not have for each
built-in the language syntax, so I use a normal iterator loop
int change(int amount, int* coins, int coinsSize){
int count[amount + 1];
memset(count, 0, sizeof(count));
count[0] = 1;
for (int i = 0; i < coinsSize; i++) {
for (int c = coins[i]; c <= amount; c++) {
count[c] += count[c-coins[i]];
}
}
return count[amount];
}
For an un-know reason, but it c quite slow some time when I try to submit result.
python
:¶
I can’t seem to know better way to initiation a array in python. Also, I use python to make my first implementation, planning process.
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
count = [0] * (amount + 1)
count[0] = 1
for i in coins:
for c in range(amount+1):
if c-i < 0:
continue
count[c] += count[c-i]
return count[amount]
rust
:¶
While rust have some more similar way to create array like c
, it require the variable to be constant example.
- To create and allocation array, using dynamic size variable, we have to use
vec!
impl Solution {
pub fn change(amount: i32, coins: Vec<i32>) -> i32 {
let mut count = vec![0; (amount + 1) as usize];
count[0] = 1;
for coin in coins {
for c in coin..=amount {
count[c as usize] += count[(c - coin) as usize];
}
}
count[amount as usize]
}
}
Time and memory for comparation:¶
Time Submitted | Status | Runtime | Memory | Language |
---|---|---|---|---|
08/11/2023 17:30 | Accepted | 3 ms | 5.6 MB | c |
08/11/2023 15:39 | Accepted | 2 ms | 2.1 MB | rust |
08/11/2023 15:17 | Accepted | 2 ms | 40.1 MB | java |
08/11/2023 15:09 | Accepted | 5 ms | 5.7 MB | c |
08/11/2023 09:49 | Accepted | 194 ms | 16.6 MB | python3 |
Created : August 16, 2023