动态规划
1. 深度优先算法
2. 递归解决斐波拉契数列
(1) 定义子问题;
(2) 实现要反复执行来解决子问题的部分(这一步要参考前一节讨论的递归的步骤);
(3) 识别并求解出边界条件。
function MinCoinChange(coins) {
let cache = {};
let _that = this;
this.makeChange = function (amount) {
if (!amount) return [];
if (cache[amount]) return cache[amount];
let min = [],
newMin,
newAmount;
for (let i = 0; i < coins.length; i++) {
let coin = coins[i];
newAmount = amount - coin;
if (newAmount >= 0) {
## 这里在不断的迭代,去寻找最优解
newMin = _that.makeChange(newAmount);
}
console.log("🚀 ~ MinCoinChange ~ newAmount:", newAmount);
## 退出迭代的边界条件
if (
newAmount >= 0 &&
(newMin.length < min.length - 1 || !min.length) &&
(newMin.length || !newAmount)
) {
min = [coin].concat(newMin);
console.log(min, "min");
}
}
return (cache[amount] = min);
};
}
const minCoinChange = new MinCoinChange([1, 5, 10, 25]);
console.log(minCoinChange.makeChange(36)); //[1,10,25]
const minCoinChange2 = new MinCoinChange([1, 3, 4]);
console.log(minCoinChange2.makeChange(6)); // [3, 3]
贪心算法版的硬币找零问题
贪心算法遵循一种近似解决问题的技术,通过每个阶段的局部最优选择(当前最好的解),从而达到全局的最优(全局最优解)。
- 尽量取最大的面额,减小硬币数
- 迭代有序的面额数组,从后面向前
function MinCoinChange(coins) {
this.makeChange = function (amount) {
let change = [],
total = 0;
for (let i = coins.length - 1; i >= 0; i--) {
let coin = coins[i];
while (total + coin <= amount) {
change.push(coin);
total += coin;
}
}
return change;
};
}
const minCoinChange = new MinCoinChange([1, 5, 10, 25]);
console.log(minCoinChange.makeChange(36)); //[ 25, 10, 1 ]
这样,我们就实现了贪心算法版的最小硬币找零问题,代码比动画的递归简单了很多。