代码随想录算法训练营第三十二天| 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)

相关推荐
Omics Pro22 分钟前
首个!外源天然产物综合性代谢图谱
数据库·人工智能·算法·机器学习·r语言
voidmort30 分钟前
3. 微调(Fine-tuning)与强化学习(RL)的核心思想
python·深度学习·算法
人道领域1 小时前
【LeetCode刷题日记】669.修剪二叉搜索树
开发语言·python·算法
2401_868534782 小时前
【无标题】
数据结构·r语言
Mr. zhihao2 小时前
Redis五大高级数据结构:原理-场景-底层-横向对比
数据结构·redis
QiLinkOS2 小时前
【从实验室到商业战场:发明专利如何重塑科技与企业的共生生态】
大数据·c语言·数据结构·c++·人工智能·单片机·算法
如此这般英俊2 小时前
手撕Claude Code—第一章 agent-loop
数据结构·人工智能·语言模型·自然语言处理
小白兔奶糖ovo3 小时前
【Leetcode】231. 2的幂
linux·算法·leetcode
xiaoxiaoxiaolll3 小时前
《Light: Science & Applications》合并BIC实现80倍阈值单模运行:超紧凑光子晶体激光器新突破
人工智能·算法·机器学习
Peter·Pan爱编程3 小时前
14. Lambda 表达式:随手可写的函数对象
c++·算法·ai编程