代码随想录算法训练营第三十二天| 509. 斐波那契数 、 70. 爬楼梯 、746. 使用最小花费爬楼梯

题目链接:509. 斐波那契数

解题思路:动态规划

具体思路:

首先处理边界情况,当 n 小于等于 1 时直接返回 n,接着创建一个长度为 n+1 的动态规划数组dp,用于存储每一步计算出的斐波那契数,先初始化 dp0 = 0 和 dp1 = 1 这两个基础值,最后通过循环从 2 遍历到 n,依次计算每个位置的 dpi,即dpi = dpi - 1 + dpi - 2,最终返回dpn得到第 n 项的结果。

具体代码:

cpp 复制代码
class Solution {
public:
    int fib(int n) {
        if (n <= 1) return n;
        vector<int> dp(n + 1);
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= n; i++){
            dp[i] = dp[i -1] + dp[i - 2];
        }
        return dp[n];
    }
};

时间复杂度:O(n)

空间复杂度:O(n)

由于计算第 n 项仅依赖前两项的结果,无需存储完整的 dp 数组,因此仅用长度为 2 的数组 dp 来保存最近两项的值,每次计算当前项为前两项之和sum = dp0 + dp1,再更新 dp 数组,可进一步优化空间复杂度。

具体代码:

cpp 复制代码
class Solution {
public:
    int fib(int n) {
        if (n <= 1) return n;
        int dp[2];
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= n; i++){
            int sum = dp[0] + dp[1];
            dp[0] = dp[1];
            dp[1] = sum;
        }
        return dp[1];
    }
};

时间复杂度:O(n)

空间复杂度:O(1)

题目链接:70. 爬楼梯

解题思路:动态规划

具体思路:

首先处理边界情况,当 n ≤ 1 时直接返回 n,接着创建长度为 n+1 的动态规划数组 dp,用于存储到达每一阶台阶的方法数,先初始化 dp1 = 1 爬 1 阶只有 1 种方法,dp2 = 2 爬 2 阶有两种方法,由于到达第 i 阶的方法数等于到达第 i - 1 阶再爬 1 阶和第 i - 2 阶再爬 2 阶的方法数之和,因此通过循环从 3 遍历到 n,依次计算dpi = dpi - 1 + dpi - 2,最终返回dpn得到到达第 n 阶台阶的总方法数。

具体代码:

cpp 复制代码
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n;
        vector<int> dp(n + 1);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

时间复杂度:O(n)

空间复杂度:O(n)

由于计算到达第 n 阶的方法数仅依赖前两阶的结果,无需存储完整的 dp 数组,因此仅用长度为 3 的数组dp,实际仅使用 dp1 和 dp2 两个位置,每次计算当前阶的方法数为前两阶之和sum = dp1 + dp2,再更新 dp 数组,可进一步优化空间复杂度。

具体代码:

cpp 复制代码
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n;
        int dp[3];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            int sum = dp[1] + dp[2];
            dp[1] = dp[2];
            dp[2] = sum;
        }
        return dp[2];
    }
};

时间复杂度:O(n)

空间复杂度:O(1)

题目链接:746. 使用最小花费爬楼梯

解题思路:动态规划

具体思路:

首先获取台阶花n费数组 cost 的长度 n,创建长度为 n + 1 的动态规划数组 dp,其中 dpi 表示到达第 i 个台阶的最小花费,初始化 dp0 = 0,dp1 = 0,因为题目允许从第 0 阶或第 1 阶开始爬,初始无花费,随后从 2 循环到 n,由于到达第 i 阶的最小花费只能由两种方式得到,从第 i - 1 阶爬 1 阶加上第 i - 1 阶的花费或从第 i - 2 阶爬 2 阶加上第 i - 2 阶的花费),因此取两者中的较小值作为 dpi,即dpi = min(dpi - 1 + costi - 1, dpi - 2 + costi - 2),最终返回 dpn,即为到达楼顶的最小总花费。

具体代码:

cpp 复制代码
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        vector<int> dp(n + 1);
        dp[0] = 0;
        dp[1] = 0;
        for (int i = 2; i <= cost.size(); i++) {
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
};

时间复杂度:O(n)

空间复杂度:O(n)

由于计算到达第 i 阶的最小花费仅依赖前两阶 i - 1 和 i - 2 阶的结果,无需存储完整的 dp 数组,因此仅用长度为 2 的数组 dp 保存前两阶的最小花费,计算当前阶的最小花费取从 i - 2 阶爬 2 阶 dp0 + costi - 2和从 i - 1 阶爬 1 阶dp1 + costi - 1两种方式的最小值,再更新 dp 数组,可进一步优化空间复杂度。

具体代码:

cpp 复制代码
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        int dp[2];
        dp[0] = 0;
        dp[1] = 0;
        for (int i = 2; i <=n; i++) {
            int sum = min(dp[0] + cost[i - 2], dp[1] + cost[i - 1]);
            dp[0] = dp[1];
            dp[1] = sum;
        }
        return dp[1];
    }
};

时间复杂度:O(n)

空间复杂度:O(1)

相关推荐
红豆诗人4 分钟前
C++二叉搜索树:查找、插入和删除为什么这样写
数据结构·c++·算法
HZjiangzi4 分钟前
深耕精密驱动二十六载,捷昌驱动助力机器人产业升级发展
人工智能·算法
奋发向前wcx4 分钟前
CSP-J复赛模拟赛3 王晨旭补题 2026.10.4
算法
H.莓飛13 分钟前
【数据结构】堆_OJ题
linux·数据结构·算法
Dream it possible!30 分钟前
蓝桥杯_翻转_C++
c++·算法·蓝桥杯
Ivanqhz30 分钟前
BURG(自底向上重写生成器)
服务器·数据库·人工智能·深度学习·算法
言乐637 分钟前
逻辑回归与利弊
人工智能·算法·机器学习·数据挖掘·逻辑回归
海绵宝宝转agent1 小时前
Leetcode100 二叉树的中序遍历
java·算法
根目录下的猫1 小时前
ROS 2 C++(rclcpp)版本,实现话题订阅、话题发布,以及完整编译运行流程
开发语言·c++·算法
大侠归来3 小时前
C 语言 | 在函数中操作数组
c语言·c++·算法