思路:对于可以选择的面值(面值比num都大,当然不可选),一次选择0次~最多选择的次数,然后递归下去,子函数只能从后面的货币开始选。
import java.util.ArrayList; import java.util.List; public class Solution { int[] money = { 25, 10, 5, 1 }; public List<List<Integer>> wayOfChange(int num) { List<List<Integer>> res = new ArrayList<List<Integer>>(); List<Integer> tmp = new ArrayList<Integer>(); wayOfChangeRec(res, tmp, num, 0); return res; } private void wayOfChangeRec(List<List<Integer>> res, List<Integer> tmp, int num, int start) { if (num < 0) return; if (num == 0) { res.add(new ArrayList<Integer>(tmp)); return; } // 从start开始寻找可以继续添加的元素 int i = start; while (i < money.length && num < money[i]) i++; if (i >= money.length) return; // 计算当前面值最多可以用几次 int times = num / money[i]; // 依次选择0次,1次,2次...times次 for (int k = 0; k <= times; k++) { for (int j = 0; j < k; j++) tmp.add(money[i]); // 递归向下,后面只能从后面的面值开始选 wayOfChangeRec(res, tmp, num - k * money[i], i + 1); for (int j = 0; j < k; j++) tmp.remove(tmp.size() - 1); } } public static void main(String[] args) { System.out.println(new Solution().wayOfChange(9)); } }