「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战」
楼梯问题
爬楼梯
动态规划
假设当前台阶为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);
简单吧?
简单请点个赞吧