码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 代碼隨想錄算法訓練營|第五十二天|123 买卖股票的最佳时机III、188 买卖股票的最佳时机IV。刷题心得(c++)


    目录

    讀題

    123 买卖股票的最佳时机III

    自己看到题目的第一想法

    看完代码随想录之后的想法

    188 买卖股票的最佳时机IV

    自己看到题目的第一想法

    看完代码随想录之后的想法

    123 买卖股票的最佳时机III - 實作

    思路

    Code

    188 买卖股票的最佳时机IV - 實作

    思路

    Code

    總結

    自己实现过程中遇到哪些困难

    今日收获,记录一下自己的学习时长

    相關資料


    讀題

    123 买卖股票的最佳时机III

    自己看到题目的第一想法

    看到的時候我在想是不是就擴展兩格去紀錄的第一次最高以及第二次最高,但思考過後發現無法實現,因為有可能會有重複計算的問題,思考了很久沒有解法。

    看完代码随想录之后的想法

    分為五個狀態,就是不操作,第一次持有\不持有、第二次持有\不持有

    太清晰了,因為透過維護兩個持有的值,來求出最後的結果,在II中,可以多次買賣,所以只要不斷的去維護最後的總数,但在這個題目透過堆疊,去把第一次的獲利與第二次的獲利統合在一個狀態當中。

    188 买卖股票的最佳时机IV

    自己看到题目的第一想法

    這題只是123的一個小變形而已,只是將原本的兩次改為k,在這邊就要定義好dp下標的含意,其實其他部份都一樣。

    看完代码随想录之后的想法

    看完之後跟我的想法差不多,只是卡哥的做法是for循環裡面直接做兩次運算,我是會跑比較多的循環数,但整體概念因為有123的概念,所以基本上就是把買賣次数給抽象化出來。

    123 买卖股票的最佳时机III - 實作

    思路

    1. 定義DP數組以及下標的含意

      分為五種狀況

      dp[i][0] 不操作

      dp[i][1] 第一次持有

      dp[i][2] 第一次不持有 (得到第一次持有的獲利)

      dp[i][3] 第二次持有

      dp[i][4] 第二次不持有 (得到第二次持有的獲利)

    2. 遞推公式

      dp[i][0] = dp[i - 1][0]

      dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]) (上一次持有的金額與上一次不操作持有目前的股票,哪個比較值得)

      dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]) (上一次獲利的金額與持有上一次的股票目前賣出,哪個比較值得)

      dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]) (上一次獲利的現金買入目前的股票與持有上一次的股票獲利,哪個比較值得)

      dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]) (上一次使用第第一次買入的獲利與上一次買入的股票在今天才賣,哪個比較值得)

    3. 根據遞推公式、題意以及定義,確定DP數組如何初始化

      dp[0][0] = 0 → 不操作

      dp[0][1] = -prices[0] → 第一次持有

      dp[0][2] = 0 第一次不持有(-prices[0] + prices[0])

      dp[0][3] = -prices[0] → 第二次持有 (今天我買了又賣了又買了)

      dp[0][4] = 0 → 第二次不持有

    4. 確定遍歷順序

      是透過前面的狀況推導出後面的狀況,所以是由前往後遍歷

    Code

    1. class Solution {
    2. public:
    3. int maxProfit(vector<int>& prices) {
    4. vectorint>> dp (prices.size(), vector<int>(5,0)) ;
    5. dp[0][1] = -prices[0];
    6. dp[0][3] = -prices[0];
    7. for(int i = 1; i < prices.size(); i++) {
    8. dp[i][0] = dp[i - 1][0];
    9. dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
    10. dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
    11. dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
    12. dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
    13. }
    14. return dp[prices.size() - 1][4];
    15. }
    16. };

    188 买卖股票的最佳时机IV - 實作

    思路

    1. 定義DP數組以及下標的含意

      分為三種狀況

      dp[i][0] 不操作

      dp[i][j]: 有兩種狀況,持有與不持有

      dp[i][2 * k - 1] 第 2 * k -1 持有

      dp[i][2 * k] 第 2 * k不持有

    2. 遞推公式

      基本上跟123一致,只是要去遍歷2 * k 次数組,去逐步更新数組

      持有 dp[i][j] = max (dp[i - 1][j], dp[i - 1][j - 1] - prices[0]);

      不持有 dp[i][j] = max (dp[i - 1][j], dp[i - 1][j - 1] + prices[0]);

      持有跟不持有的部份可以根據觀察發現,在%2時,持有是1,不持有是0,透過這個方式更新数組

    3. 根據遞推公式、題意以及定義,確定DP數組如何初始化

      在dp[i][j]時,在單數時都設定為持有的狀況。

    4. 確定遍歷順序

      是透過前面的狀況推導出後面的狀況,所以是由前往後遍歷

    Code

    1. class Solution {
    2. public:
    3. int maxProfit(int k, vector<int>& prices) {
    4. vector<vector<int>> dp (prices.size(), vector(2 * k + 1,0)) ;
    5. for(int i = 1; i < 2 * k + 1; i+=2) {
    6. dp[0][i] = -prices[0];
    7. }
    8. for(int i = 1; i < prices.size(); i++) {
    9. dp[i][0] = dp[i - 1][0];
    10. for(int j = 1; j < 2 * k + 1; j++) {
    11. if(j % 2 == 1) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] - prices[i]);
    12. else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + prices[i]);
    13. }
    14. }
    15. return dp[prices.size() - 1][2 * k];
    16. }
    17. };

     

    總結

    自己实现过程中遇到哪些困难

    在第一個部份透過講解對於題目有比較深刻的理解,今天的難點主要是在思路上,思路講解清楚後,對於下一道題目就可以舉一反三了

    今日收获,记录一下自己的学习时长

    今天大概學習了1.5hr,主要把第一個題目思路釐解清楚,後面那道題目就比較容易解決了。

    相關資料

    ● 今日学习的文章链接和视频链接

    详细布置

    123.买卖股票的最佳时机III

    视频讲解:动态规划,股票至多买卖两次,怎么求? | LeetCode:123.买卖股票最佳时机III_哔哩哔哩_bilibili

    https://programmercarl.com/0123.买卖股票的最佳时机III.html

    188.买卖股票的最佳时机IV

    视频讲解:动态规划来决定最佳时机,至多可以买卖K次!| LeetCode:188.买卖股票最佳时机4_哔哩哔哩_bilibili

    https://programmercarl.com/0188.买卖股票的最佳时机IV.html

  • 相关阅读:
    踩到一个关于分布式锁的非比寻常的BUG!
    Android BitmapUtil图片工具类
    vivado产生报告阅读分析7-时序报告3
    【Pytorch深度学习开发实践学习】B站刘二大人课程笔记整理lecture11 Advanced_CNN 实现GoogleNet和ResNet
    0907小众网,续0906,SSM前后端项目,思路,报错(重点)
    混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.1)
    内网服务器无法访问外网下载时,制作本地清华镜像源,搭建中转服务器(rinted)
    Linux基础命令
    Linux保姆级安装及配置教程
    【单细胞高级绘图】10.KEGG富集结果的圆圈图
  • 原文地址:https://blog.csdn.net/RVLIN/article/details/134069704
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号