硬币
难度:
标签:
题目描述
Given an infinite number of quarters (25 cents), dimes (10 cents), nickels (5 cents), and pennies (1 cent), write code to calculate the number of ways of representing n cents. (The result may be large, so you should return it modulo 1000000007)
Example1:
Input: n = 5 Output: 2 Explanation: There are two ways: 5=5 5=1+1+1+1+1
Example2:
Input: n = 10 Output: 4 Explanation: There are four ways: 10=10 10=5+5 10=5+1+1+1+1+1 10=1+1+1+1+1+1+1+1+1+1
Notes:
You can assume:
- 0 <= n <= 1000000
代码结果
运行时间: 41 ms, 内存: 15.9 MB
/*
* Problem: Given unlimited coins with values 25, 10, 5, and 1 cents, write code to calculate the number of ways to represent n cents.
* The result can be very large, so you need to return the result modulo 1000000007.
*
* Approach using Java Streams:
* This solution uses a similar dynamic programming approach as the previous one, but leverages Java Streams for more concise code.
*/
import java.util.stream.IntStream;
public class CoinChangeStream {
public static int countWays(int n) {
int MOD = 1000000007;
int[] coins = {25, 10, 5, 1};
int[] dp = new int[n + 1];
dp[0] = 1;
for (int coin : coins) {
dp = IntStream.range(coin, n + 1).boxed()
.mapToInt(i -> (dp[i] + dp[i - coin]) % MOD)
.toArray();
}
return dp[n];
}
public static void main(String[] args) {
System.out.println(countWays(5)); // Output: 2
System.out.println(countWays(10)); // Output: 4
}
}
解释
方法:
此题解采用动态规划类似的方法,但优化了空间复杂度。首先,考虑最大的硬币25分,从0枚到最多可能的枚数遍历,每次减去25分硬币占的总额后,计算剩余金额可以由10分和5分硬币组合的方式。这里利用了组合数学中的简单排列组合原理,即固定某些硬币后,其余硬币的组合方式数量。对于每个i(25分硬币的数量),计算剩余金额可以由10分硬币最多可以有多少枚(a),以及5分硬币最多可以有多少枚(b)。然后用组合方式计算这些硬币可以组合成剩余金额的方法数。最后,所有可能的i的总和即为答案。
时间复杂度:
O(n/25) 或简化为 O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
题解中提到了`计算剩余金额可以由10分和5分硬币组合的方式`,请问这种组合方式是如何确保覆盖所有可能的硬币组合?
▷🦆
在动态规划的优化过程中,为何选择只使用常数个变量而不使用数组来维护状态?这种方式有什么优缺点?
▷🦆
题解中的`ans += (a + 1) * (a + b + 1)`计算方式是基于什么组合数学的原理?能否具体解释其正确性?
▷