一、题目
硬币问题:
Given an infinite number of quarters (25 cents), dimes (10 cents), nickels (5 cents) and pennies (1 cent), find how many ways to represent n cents.
二、思路及其代码实现
思路一:多路递归
下面两种方法是同一思路的不同实现,练习的时候顺手打的。
实现(一)
/**
* way01——多路递归1
* @param coins 面值数组(需正序排列)
* @param n 凑n
* @param current 当前判断的面值下标 从0开始:小面值到大面值
* @return 组合次数
*/
static int count = 0;
public static int recursion(int[] coins, int n, int current) {
if (n < 0) return 0;//考虑键入n负数情况
if (n == 0) {//刚好凑整,累计次数
count++;
return count;
}
if (n < coins[current]) return 0;//当要n<当前面值时,说明此种选择无效
if (current == coins.length) return 0;//若current越界都未达到n==0的情况,则此种选择无效
for (int i = 0; i <= n / coins[current]; i++) {//当前面值个数可选范围:0——n/coins[current]
recursion(coins,n - i * coins[current],current + 1);
}
return count;
}
实现(二)
/**
* way02——多路递归2
* @param coins 需正序排列
* @param n
* @param current 从coins.length开始:大面值到小面值
* @return
*/
public static int recursion02(int[] coins, int n, int current) {
if (n < 0) return 0;//考虑键入n负数情况
int amount = 0;
if (current == 0) return 1;//current==0,面值为1,可凑整n,此种选择有效。
for (int i = 0; i <= n / coins[current]; i++) {//当前面值个数可选范围:0——n/coins[current]
amount += recursion02(coins,n - i * coins[current],current - 1);
}
return amount;
}
}
思路二:DFS
三、同类题目
1、著名编程网站ProjectEuler:
假设我们有8种不同面值的硬币{1, 2, 5, 10, 20, 50, 100, 200} ,用这些硬币组合构成一个给定的数值n。
例如n=200,那么一种可能的组合方式为200 = 3 * 1 + 1 * 2+ 1 * 5 + 2 * 20 + 1 * 50 + 1 * 100。
问总共有多少种可能的组合方式?
2、华为面试题:
1分2分5分的硬币三种,组合成1角, 共有多少种组合
eg: 1x + 2y+ 5z = 10
3、创新工厂笔试题:
有1分,2分,5分, 10分四种硬币,每种硬币数量无限,给定n分钱,有多少组合可以组成n分钱。