2026-2-9:LeetCode每日一题(动态规划专项)

爬代价楼梯

题目描述:

给你一个整数数组 cost ,其中 costi 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

难于昨天的楼梯

昨天的爬楼梯https://blog.csdn.net/2401_87095818/article/details/157910173?fromshare=blogdetail&sharetype=blogdetail&sharerId=157910173&sharerefer=PC&sharesource=2401_87095818&sharefrom=from_link

解法一:(递归版)

源码:

cpp 复制代码
class Solution {

    int n1(int n, vector<int>& cost, vector<int>& vis) {
        if (n > 2) {
            if (vis[n] != 0) {
                return vis[n];
            } else {
                vis[n] = min(n1(n - 1, cost, vis) + cost[n - 1],
                             n1(n - 2, cost, vis) + cost[n - 2]);
                return vis[n];
            }
        } else {
            if (n == 1) {
                return 0;
            } else {
                return min(cost[0], cost[1]);
            }
        }
    }

public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        vector<int> vis(n + 1);
        return n1(n, cost, vis);
    }
};

说明:

超时了

解法二:

源码:

cpp 复制代码
class Solution {
    int n1(int n, vector<int>& cost, vector<int>& vis) {
        vis[1] = 0;
        vis[2] = min(cost[0], cost[1]);
        for (int i = 3; i <= n; i++) {
            vis[i] = min(vis[i - 1] + cost[i - 1], vis[i - 2] + cost[i - 2]);
        }
        return vis[n];
    }

public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        vector<int> vis(n + 1);
        return n1(n, cost, vis);
    }
};

说明:

递归太耗时了,循环替代。

解法三:

源码:

cpp 复制代码
class Solution {
    int n1(int n, vector<int>& cost) {
        if (n == 1) return 0;
        if (n == 2) return min(cost[0], cost[1]);
        
        int a = 0; // 对应vis[1]
        int b = min(cost[0], cost[1]); // 对应vis[2]
        int res = 0;
        
        for (int i = 3; i <= n; i++) {
            res = min(b + cost[i - 1], a + cost[i - 2]);
            a = b;
            b = res;
        }
        return res;
    }

public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        return n1(n, cost);
    }
};

说明:

去掉数组,进一步压缩空间

总结

递归超时有3个主要原因:

1.函数调用栈的硬开销(主要原因)

递归的每一次调用,系统都需要:

  • 为函数创建栈帧(保存返回地址、参数、局部变量);
  • 把参数(n、cost、vis)从当前函数复制到新函数;
  • 函数执行完成后,销毁栈帧并返回结果;

2.缓存访问的开销

递归函数中存在一些判断,多次调用多次判断

3.系统对递归的限制

操作系统对函数栈的深度有上限,超出会直接触发栈溢出错误,而迭代没有这个限制

相关推荐
凯瑟琳.奥古斯特44 分钟前
力扣1235:加权区间调度最优解
java·python·算法·leetcode·职场和发展
耶叶1 小时前
餐厅出入最少人数问题:贪心算法
算法·贪心算法
gihigo19981 小时前
基于小波框架与稀疏表示的SAR图像目标识别系统(MATLAB实现)
算法
胡图图不糊涂^_^1 小时前
测试用例篇——设计测试用例的方法
笔记·学习·测试用例·判定表法·正交法生成用例测试·等价类·边界值
吴可可1231 小时前
CAD2004自定义实体开发环境配置
c++·算法
装不满的克莱因瓶1 小时前
矩阵的主成分是什么?主成分分析(PCA)又能做什么?
人工智能·线性代数·算法·机器学习·ai·矩阵·pca
大菜菜小个子1 小时前
template<typename T>使用
java·开发语言·算法
Fanfanaas2 小时前
C++ 继承
java·开发语言·jvm·c++·学习·算法
lqqjuly2 小时前
模型合并与融合:理论、算法与可运行实现—从损失曲面几何到多模型融合
算法