这是一个求最值的问题,可以用动态规划来解。
我们以
coins = [1, 2, 5], amount = 11
为例从后往前思考:
要寻求11的最少次数就需要先找到10,9,6的最少次数然后+1求最小值即可。 而找10的最少次数需要找9,8,5的最少次数然后+1求最小值即可。...以此类推。
图中红色部分表明了计算过程中有重复计算的问题。需要避免掉,防止算法超时。
function coinChange(coins: number[], amount: number): number {
const cache: number[] = []; // 缓存已经算过的结果
const _coinChange = (coins: number[], amount: number) => {
if (amount === 0) {
return 0;
}
if (coins.includes(amount)) {
return 1;
}
if (cache[amount]) {
return cache[amount];
}
const arr = coins.map((item) => {
if (item > amount) {
// 凑不出来
return -1;
}
const change = _coinChange(coins, amount - item);
if(change === -1) {
return change;
}
// 可以凑出就把结果+1
return change + 1;
});
// 去掉-1
const changeArr = arr.filter(item => item !== -1);
// 我们只要最少次数
const minTime = changeArr.length ? Math.min.apply(Math, changeArr) : -1;
// 加缓存
cache[amount] = minTime;
return minTime;
}
return _coinChange(coins, amount);
};