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

相关推荐
小O的算法实验室5 小时前
IEEE TASE,基于MPC的多无人机协同搜索竞争群体优化方法
算法
小飞学编程...5 小时前
【哈希表】
数据结构·哈希算法·散列表
Tbisnic5 小时前
BGE-M3 算法详解:从模型架构到三种检索方式的数学原理
算法·自然语言处理·大模型·bert·transformer·注意力机制
Brilliantwxx6 小时前
【算法从零到千】【55-58】哈希位图+常见数学运算 接口
算法
空堂与归7 小时前
用户分群找不到规律?用K-Means聚类算法自动发现数据模式
算法·机器学习·kmeans·聚类
动词ing7 小时前
【C语言】自定义函数+指针入门
c语言·开发语言·算法
重生之后端学习7 小时前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
一只小小的芙厨8 小时前
基础数论总结
笔记·学习·算法
动词ing8 小时前
【C语言】结构体+文件基础
c语言·开发语言·数据结构
夜不会漫长9 小时前
C++入门(1)
开发语言·c++·算法