[路飞]_今夜爬楼梯

265 阅读3分钟

「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

1143. 最长公共子序列

楼梯问题

70. 爬楼梯
746. 使用最小花费爬楼梯

爬楼梯

动态规划

假设当前台阶为x;

因为每次可以跨1级台阶。也可以跨2级台阶

所以如果想到达x台阶,最少要到达x-2或者x-1台阶;

所以递推公式 f(x) = f(x-1)+f(x-2);

根据上述思路编辑代码如下:

var climbStairs = function(n) {
    let array = [0,1,2,3]
    if(n < 4) return array[n]
    for(let i = 3 ; i <= n ; i++){
        array[i] = array[i-1]+array[i-2]
    }
    return array[n]
};

空间复杂度O(n);其实还是可以优化的;

状态压缩

压缩状态,上述数组中数据咱们只用了一次,如果可以将数据保存到下一执行过程,则不需要保存全部数组数据;

假设初始数组[0,0,1];

在计算第1位的时候:

将数组第1位移动到第0位

将数组第2位移动到第1位

移动后数组位[0,1,1]; 则第1位是0+1 = 1;

同理计算第2位;

移动后数组为[1,1,1]

计算后数组位[1,1,2]

计算第3位

转移后数组位[1,2,2]

计算后数组为[1,2,3]

所以只需输出数组最后一位即可得到答案,且时间复杂度为O(1)

jis

var climbStairs = function (n) {
  let [a0, a1, a2] = [0, 0, 1]
  for (let i = 1; i <= n; ++i) {
      // 压缩位置,将数组第1位移动到第0位
      // 第二位移动到
    a0 = a1
    a1 = a2
    a2 = a0 + a1
  }
  return a2
}

使用最小花费爬楼梯

上一个问题是爬楼梯有多少中方法;(所有可能)

这个问题问的是爬楼梯最小的花费;(所有可能花费最少)

那我们是不是也可以接上题思路;

假设当前在x楼梯;

因为每次可以跨1级台阶。也可以跨2级台阶

所以到达x需要的花费是到达 x-1,x-2台阶的较小值;

即:f(x) = min(f(x-1),f(x-2))

状态方程找到,上代码

var minCostClimbingStairs = function (cost) {
     const len = cost.length;
    //前两步花费为0;
    const stepCost = [0,0]
    for(let i = 2 ; i <= len ; i++){
        //下一步的费用,上一步费用与上上一步费用较小值
        stepCost[i] = Math.min(cost[i-1]+stepCost[i-1] , cost[i-2]+stepCost[i-2])
    }
    return stepCost[len]

};

时间复杂度O(n)
空间复杂度O(n)

都是爬楼梯,都用到数组存储数据,你能用状态压缩,我当然也能用状态压缩!!

状态压缩

怎么压缩呢?观察

数组始终用到3个变量,a0,a1,a2;

初始值a0 = a2 = 0;a2需要计算的值;

所以带入代码可得到:


var minCostClimbingStairs = function (cost) {
     const len = cost.length;
     let a0 = 0;
     let a1 = 0;
     let a2;
    for(let i = 2 ; i <= len ; i++){
        //下一步的费用,上一步费用与上上一步费用较小值
        a2 = Math.min(cost[i-1]+a1 , cost[i-2]+a0)
        a0 = a1;
        a1 = a2;
    }
    return a2

};

空间复杂度降低为O(1);

简单吧?

简单请点个赞吧