刷题打卡day38:第九章 动态规划part01 理论基础 、 509. 斐波那契数、 70. 爬楼梯、 746. 使用最小花费爬楼梯

文章讲述了在找实习期间因迷茫中断刷题的经历,并决心恢复学习节奏。文中通过斐波那契数列和爬楼梯问题介绍了动态规划的五步解题法,强调初始化dp数组的重要性,并展示了如何优化空间复杂度从O(n)降至O(1)。同时提到了面试过程中的体验,指出算法岗位的竞争激烈,需要持续努力。
摘要由CSDN通过智能技术生成

        时隔将近20天没有刷题,这20天在找实习中,迷茫了思绪。打断了自己的节奏。甚至基本没干什么。每天陷在自我纠结、内耗中。失意、摆烂、振作、乱。循环往复。反正是这20天基本没学什么东西。之后不能这样了,不能被任何事情打断自己的节奏,必须每天保证完成自己的刷题任务、求职知识学习任务、课题导师任务也要让老师满意。在此立个flag:不荒废每天的时间,直到找到心仪的工作。学习时候不能总想看b站、被其他事情打断自己的节奏。

        所幸结果不算太坏,算是求上得中了吧。至少导师能放我一小段时间就是胜利。真心感谢我的导师。还有帮助我的师兄。在此就不说名字了。

        在这期间面试了一些中小公司,也了解了一些东西。希望在之后的日子里抓紧冲。毕竟算法岗卷到爆炸,想进去使用全部力气甚至不容易,更何况不用力气呢?千万不能在水了!!!!

下面开始继续刷题!

  

第九章 动态规划part01

 理论基础

五步走:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

509. 斐波那契数

比较简单,用来熟悉动规五步走

需要注意的就是:定义dp数组

 vector<int> dp(N + 1);

定义dp数组时,能初始化完整就初始化完整,比如大小和初始化的值。这里因为要求dp(n),从0开始,所以大小为n+1.

第二个需要注意的就是改进的方法。

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):一个for循环。
  • 空间复杂度:O(n):开辟了一个大小为n+1的数组。

可以对其进行改进,因为dp(n)只与他的前两个值相关,因此可以只维护前两个值。将空间复杂度降低到O(1).

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):for循环
  • 空间复杂度:O(1):只维护dp[0]和dp[1]。循环使用。记住此时定义dp数组时,初始大小是2就可以了。不要多定义。

70. 爬楼梯

和上面那道题一样

n个楼梯时的方法就是n-1个楼梯爬一步和n-2个楼梯爬两步,懂这个就可以了。

class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n; // 因为下面直接对dp[2]操作了,防止空指针
        vector<int> dp(n + 1);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) { // 注意i是从3开始的
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

746. 使用最小花费爬楼梯 

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        vector<int> dp(cost.size() + 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[cost.size()];
    }
};

这个需要注意dp数组大小,是提供的数组的大小+1,因为索引从0开始。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值