动态规划之爬楼梯问题,学会第四种解法将是面试中一大亮点!!

549 阅读2分钟

问题描述

剑指offer88题:爬楼梯的最少成本 image.png

解法一:自上而下递归

const cost = [1, 100, 1, 1, 100, 1]
// 得到爬上该楼梯的最小花费
function minCost(cost) {
    const length = cost.length
    /** 为什么这里不用 + cost[i]?你仔细想想:helpler 函数得到的其实是第 i 层向上爬所需要的花费也就是说: 
     ** 我们只需要判断 length 层向上爬和 length - 1 层向上爬的那个花费比较小就可以了
     */
    return Math.min(helper(cost, length - 1), helper(cost, length - 2));
    // tips:因为索引是从 0 开始,所以 length - 1 代表第 length 层
}

// 得到第 i 层向上爬所需要的花费
function helper(cost, i) {
    if (i < 2) return cost[i];

    return Math.min(helper(cost, i - 1), helper(cost, i - 2)) + cost[i]
}

console.log(minCost(cost));

解法二:缓存结果减少重复计算

const cost = [1, 100, 1, 1, 100, 1]

function minCost(cost) {
    const length = cost.length;
    // 将计算结果缓存到 dep 中不重复计算,dep[0]的值就是从第1层向上爬所需要的花费
    const dep = [cost[0], cost[1]];
    helper(cost, length - 1, dep);
    return Math.min(dep[length - 2], dep[length - 1])
}

// 为 dep[level] 赋值
function helper(cost, level, dep) {
    // dep[0], dep[1] 已经赋值无需重复赋值
    if (level < 2) return;
    // 只有在 dep[level] 没有赋值的情况才需要赋值
    if (!dep[level]) {
        // 要求 dep[level] 首先得为 dep[level - 1] 和 dep[level - 2] 赋值
        helper(cost, level - 1, dep);
        helper(cost, level - 2, dep);
        dep[level] = Math.min(dep[level - 1], dep[level - 2]) + cost[level];
    }
}

console.log(minCost(cost));

解法三:自下而上的写法

这种解法比较好理解,耐心看下第四种解法!!

const cost = [1, 100, 1, 1, 100, 1]

function minCost(cost) {
    const length = cost.length;
    const dep = [cost[0], cost[1]]
    for (let i = 2; i < length; i++) {
        dep[i] = Math.min(dep[i - 1], dep[i - 2]) + cost[i]
    }

    return Math.min(dep[length - 1], dep[length - 2]);
}

console.log(minCost(cost));

解法四:再次优化,其实每次计算完只需保留前两个的结果

const cost = [1, 100, 1, 1, 100, 1]

function minCost(cost) {
    const length = cost.length;
    const dep = [cost[0], cost[1]]
    for (let i = 2; i < length; i++) {
        // 改动, i%2 说明 i = 2 的时候回替换掉 dep[0] 的数,旧的 dep[0](求下一个解并不需要它),以此类推...
        dep[i % 2] = Math.min(dep[0], dep[1]) + cost[i]
    }

    return Math.min(dep[0], dep[1]);
}

console.log(minCost(cost));

总结

这篇文章是本人对《剑指offer》动态规划14.1的一个总结,希望对大家有帮助,有条件的可以看看原著,这是第一次发表文章,如果感觉还不错的话就给个三连吧,也算是我后续创作的一种激励,也欢迎大家在评论区批评指正,祝各位早日拿到自己心仪的 offer!

后话

立个 flag,在下周末会对 14.2 也做一个总结