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.系统对递归的限制

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

相关推荐
To_OC10 小时前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
用户9385156350715 小时前
从 O(n²) 到 O(nlogn):一文读懂快速排序的“快”与“妙”
javascript·算法
To_OC16 小时前
手写快排次次翻车?别死背快排模板了,这才是面试官想听的底层逻辑
javascript·算法·排序算法
饼干哥哥17 小时前
Reddit VOC调研太慢?搭一个AI专家团队半小时洞察任何品类|以猫用饮水机为例
人工智能·算法·ai编程
地平线开发者18 小时前
Transformer模型部署之性能优化指南
算法
地平线开发者18 小时前
人在途中:从“编译失败”到“模型可落地”——CUDA 自定义算子
算法·自动驾驶
半个落月21 小时前
从递归到快速排序:用 JavaScript 把分治思想讲明白
javascript·算法·面试
小月土星1 天前
JavaScript 快速排序:从 pivot、双指针到分治思想
javascript·算法·面试
小月土星1 天前
JavaScript 递归入门:从 1 到 n 求和,再到数组扁平化
javascript·算法·面试