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

爬代价楼梯

题目描述:

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 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.系统对递归的限制

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

相关推荐
今天你TLE了吗2 小时前
JVM学习笔记:第三章——运行时数据区(部分)
jvm·笔记·学习
BOTTLE_平2 小时前
C++图论全面解析:从基础概念到算法实践
c++·算法·图论
Lenyiin2 小时前
《 C++ 修炼全景指南:二十四 》彻底攻克图论!轻松解锁最短路径、生成树与高效图算法
c++·算法·图论·邻接表·邻接矩阵·最小生成树·最短路径
瓦特what?2 小时前
冒 泡 排 序
开发语言·数据结构·c++
YGGP2 小时前
【Golang】LeetCode 41. 缺失的第一个正数
算法·leetcode·职场和发展
田里的水稻2 小时前
FA_规划和控制(PC)-动态窗口(DWA)
人工智能·算法·数学建模·机器人·自动驾驶
Katecat996632 小时前
【YOLOv8+CAA+HSFPN】频率检测识别算法改进与实现_1
算法·yolo
卷卷的小趴菜学编程2 小时前
项目篇----使用基数树对性能进行优化
算法·tcmalloc
CHANG_THE_WORLD2 小时前
深入指针4 - 学习笔记整理
笔记·学习·算法