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

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

解题思路:动态规划

具体思路:

首先处理边界情况,当 n 小于等于 1 时直接返回 n,接着创建一个长度为 n+1 的动态规划数组dp,用于存储每一步计算出的斐波那契数,先初始化 dp[0] = 0 和 dp[1] = 1 这两个基础值,最后通过循环从 2 遍历到 n,依次计算每个位置的 dp[i],即dp[i] = dp[i - 1] + dp[i - 2],最终返回dp[n]得到第 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 = dp[0] + dp[1],再更新 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,用于存储到达每一阶台阶的方法数,先初始化 dp[1] = 1 爬 1 阶只有 1 种方法,dp[2] = 2 爬 2 阶有两种方法,由于到达第 i 阶的方法数等于到达第 i - 1 阶再爬 1 阶和第 i - 2 阶再爬 2 阶的方法数之和,因此通过循环从 3 遍历到 n,依次计算dp[i] = dp[i - 1] + dp[i - 2],最终返回dp[n]得到到达第 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,实际仅使用 dp[1] 和 dp[2] 两个位置,每次计算当前阶的方法数为前两阶之和sum = dp[1] + dp[2],再更新 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,其中 dp[i] 表示到达第 i 个台阶的最小花费,初始化 dp[0] = 0,dp[1] = 0,因为题目允许从第 0 阶或第 1 阶开始爬,初始无花费,随后从 2 循环到 n,由于到达第 i 阶的最小花费只能由两种方式得到,从第 i - 1 阶爬 1 阶加上第 i - 1 阶的花费或从第 i - 2 阶爬 2 阶加上第 i - 2 阶的花费),因此取两者中的较小值作为 dp[i],即dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]),最终返回 dp[n],即为到达楼顶的最小总花费。

具体代码:

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 阶 dp[0] + cost[i - 2]和从 i - 1 阶爬 1 阶dp[1] + cost[i - 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)

相关推荐
沐苏瑶7 小时前
Java 搜索型数据结构全解:二叉搜索树、Map/Set 体系与哈希表
java·数据结构·算法
ccLianLian7 小时前
深度学习·DDPM
数据结构
ZoeJoy88 小时前
算法筑基(二):搜索算法——从线性查找到图搜索,精准定位数据
算法·哈希算法·图搜索算法
Alicx.8 小时前
dfs由易到难
算法·蓝桥杯·宽度优先
_日拱一卒8 小时前
LeetCode:找到字符串中的所有字母异位词
算法·leetcode
云泽8088 小时前
深入 AVL 树:原理剖析、旋转算法与性能评估
数据结构·c++·算法
Wilber的技术分享9 小时前
【LeetCode高频手撕题 2】面试中常见的手撕算法题(小红书)
笔记·算法·leetcode·面试
邪神与厨二病9 小时前
Problem L. ZZUPC
c++·数学·算法·前缀和
梯度下降中10 小时前
LoRA原理精讲
人工智能·算法·机器学习
IronMurphy11 小时前
【算法三十一】46. 全排列
算法·leetcode·职场和发展