LeetCode买卖股票的最佳时机系列总结

此类动态规划从二维动规理解后优化到一维动规,部分题目还可以用到贪心。

目录:

121 买卖股票的最佳时机1
122 买卖股票的最佳时机2
123 买卖股票的最佳时机3
188 买卖股票的最佳时机4
309 买卖股票的最佳时机+冷冻期

714 买卖股票的最佳时机+手续费(2的基础上卖出时-手续费)

121 买卖股票的最佳时机(买卖一次

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个
算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

输入:[7,1,5,3,6,4]
输出:5 解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 =
6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

二维动规
int maxProfit(vector<int>& prices) {int n = prices.size();if(n == 1)return 0;vector<vector<int>>dp(n, vector<int>(2));dp[0][0] = 0;                 // 不持有 = 卖出+还没买dp[0][1] = -prices[0];        // 持有 买过还没卖for(int i = 1; i < n; ++i) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);//第i天不持有 = max(第i - 1不持有, i - 1天持有+今天卖出)dp[i][1] = max(dp[i - 1][1],  -prices[i]);//第i天持有 = max(第i - 1持有, 今天买入,只买一次)}return dp[n - 1][0];}
一维动规O(N)/O(1)
每一天的状态只与前一天的状态有关,把dp[i - 1][1],dp[i - 1][0]存在两个变量中,
计算出dp[i][1],dp[i][0]在存回对应变量即可
int maxProfit(vector<int>& prices) {int n = prices.size();if(n == 1)return 0;int sell = 0;                // 不持有 = 卖出+还没买int buy = -prices[0];        // 持有 买过还没卖for(int i = 0; i < n; ++i) {int newbuy = max(buy, -prices[i]);int newsell = max(sell, buy + prices[i]);sell = newsell;buy = newbuy;}return sell;}
贪心:
int maxProfit(vector<int>& prices) {int n = prices.size();if(n == 1)return 0;int maxn = 0;int start = prices[0];for(int i = 1; i < n; ++i) {if(prices[i] < start) start = prices[i];//下一个小于假设买入的价格,更新startelse maxn = max(maxn, prices[i] - start);//更新最大利润}return maxn;}

122 买卖股票的最佳时机2 (买卖多次)

给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

二维动规
定义状态dp[i][1] 表示第i天交易完后手里没有股票的最大利润,
dp[i][0] 表示第i天交易完后手里持有一支股票的最大利润(i从0开始)。int maxProfit(vector<int>& prices) {int n = prices.size();vector<vector<int>>dp(n, vector<int>(2));dp[0][0] = - prices[0];  //持有dp[0][1] = 0;            //未持有for(int i = 1; i < n; ++i) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);//第i天持有 = max(第i - 1持有, i - 1天不持有今天买入)和1不同dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);}return dp[n - 1][1];}
};
一维动规
int maxProfit(vector<int>& prices) {int n = prices.size();int dp0 = -prices[0];int dp1 = 0;for(int i = 1; i < n; ++i) {int newdp0 = max(dp0, dp1 - prices[i]);int newdp1 = max(dp1, dp0 + prices[i]);dp0 = newdp0;dp1 = newdp1;}return dp1;}
贪心,收集所有上坡,和是最大int maxProfit(vector<int>& prices) {int n = prices.size();int maxn = 0;for(int i = 1; i < n; ++i) maxn += max(0, prices[i] - prices[i - 1]);return maxn;}

123 买卖股票最佳时机 (买卖2次)

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
思路:买两次状态有:无操作,第一次买入,第一次卖出,第二次买入,第二次卖出。

二维动规int maxProfit(vector<int>& prices) {int n = prices.size();if(n <= 1)return 0;vector<vector<int>>dp(n, vector<int>(5));dp[0][0] = 0;                  //无操作dp[0][1] = -prices[0];         //第一次买入dp[0][2] = 0;                  //第一次卖出dp[0][3] = -prices[0];         //第二次买入dp[0][4] = 0;                  //第二次卖出for(int i = 1; i < n; ++i) {dp[i][0] = dp[i - 1][0];dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);//第一次买入 = max(前一天无操作今天买入, 前一天已经买入)dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);//第一次卖出 = max(前一天已经卖出, 前一天买入今天卖出)dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);//第二次买入 = max(前一天已经第二次买入,前一天是第一次卖出+今天买入)dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);//第二次卖出 = max(前一天已经第二次买入。前一天是第二次买入+今天卖出)}return dp[n - 1][4];}
 一维动规;每一天的状态只与前一天的状态有关int maxProfit(vector<int>& prices) {int n = prices.size();if(n <= 1)return 0;int buy1 = -prices[0];int sell1 = 0;int buy2 = -prices[0];int sell2 = 0;for(int i = 1; i < n; ++i) {buy1 = max(buy1, -prices[i]);sell1 = max(sell1, buy1 + prices[i]);buy2 = max(buy2, sell1 - prices[i]);sell2 = max(sell2, buy2 + prices[i]);}return sell2;}

188买卖股票最佳时机 (买卖k次)

给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

二维动规int maxProfit(int k, vector<int>& prices) {int n = prices.size();if(k == 0 || n == 0)return 0;vector<vector<int>>dp(n, vector<int>(2*k + 1, 0));for(int i = 1; i < 2*k; i += 2) dp[0][i] = -prices[0]; //奇数买入for(int i = 1; i < n; i++) {for(int j = 0; j < 2*k - 1; j += 2) {dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] -prices[i]);dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);}}return dp[n - 1][2*k];}

309 买卖股票的最佳时机+冷冻期

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

二维动规int maxProfit(vector<int>& prices) {int n = prices.size();vector<vector<int>>dp(n, vector<int>(3));dp[0][0] = -prices[0];   //持有dp[0][1] = 0;            //不持有,在冷冻dp[0][2] = 0;            //不持有,不在冷冻for(int i = 1; i < n; ++i) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][2] - prices[i]);//第i天持有 = max(i - 1天持有, i - 1天不持有不在冷冻 今天买入)dp[i][1] = dp[i - 1][0] + prices[i];//第i天不持有在冷冻 = i - 1刚卖出dp[i][2] = max(dp[i - 1][2],dp[i - 1][1]);//第i天不持有不冷冻 = max(i - 1天不持有不冷冻, i - 1天冷冻)}return max(dp[n - 1][1], dp[n - 1][2]);}
一维,空间优化
int maxProfit(vector<int>& prices) {int n = prices.size();int buy = -prices[0], sell = 0, lock = 0;//持有不持有,在冷冻//不持有,不在冷冻for(int i = 0; i < n; i++) {int newbuy = max(buy, lock - prices[i]);int newsell = buy + prices[i];int newlock = max(lock, sell);buy = newbuy;sell = newsell;lock = newlock;}return max(lock, sell);
}

LeetCode买卖股票的最佳时机系列总结相关推荐

  1. 买卖股票的最佳时机系列

    买卖股票的最佳时机系列 1. 概述 2. dp 数组定义为状态 2.1 买卖股票的最佳时机 2.2 买卖股票的最佳时机 II 2.3 最佳买卖股票时机含冷冻期 2.4 买卖股票的最佳时机含手续费 3. ...

  2. LeetCode 买卖股票的最佳时机 - 超详细讲解系列题

    1.分析 使用通用方法,也即动态规划DP (1)LeetCode 121. 买卖股票的最佳时机 class Solution {public int maxProfit(int[] prices) { ...

  3. Leetcode 买卖股票的最佳时机

    买卖股票的最佳时机 题目描述: 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格. 你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖 ...

  4. “买卖股票的最佳时机” 系列——我来教你稳赚不亏~

    目录 前言 一.买卖股票的最佳时机 -->指定次数交易(1次) 1.1.dp定义 1.2.递推公式 1.3.遍历顺序 1.4.初始化 1.5.解题代码 二.买卖股票的最佳时机II -->交 ...

  5. 【dp】买卖股票的最佳时机系列题目

    文章目录 121. 买卖股票的最佳时机 122. 买卖股票的最佳时机 II 309. 最佳买卖股票时机含冷冻期 123. 买卖股票的最佳时机 III 188. 买卖股票的最佳时机 IV 121. 买卖 ...

  6. LeetCode 买卖股票的最佳时机 6道题1个解法总结

    一个方法解决6道买卖股票题:来自LeetCode题解 一.穷举框架 利用「状态」进行穷举.我们具体到每一天,看看总共有几种可能的「状态」,再找出每个「状态」对应的「选择」.我们要穷举所有「状态」,穷举 ...

  7. leetcode 买卖股票的最佳时机 II

    201 / 201 个通过测试用例 状态:通过 执行用时:2 ms 内存消耗:37.4 MB 提交时间:6 月,3 周之前 class Solution {public int maxProfit(i ...

  8. leetcode 买卖股票系列题目总结

    总结:买卖股票系列题目 1.买卖股票的最佳时机(简单) 121. 买卖股票的最佳时机 难度简单1093 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易( ...

  9. LeetCode刷题记录——买卖股票的最佳时机

    目录 1. 买卖股票的最佳时机 2. 买卖股票的最佳时机II 相信许多小伙伴在笔试和面试的时候会经常遇到 买卖股票的最佳时机的相关题目,看了这篇文章,你将会一次性掌握该系列题目的解法. 废话不多说,且 ...

最新文章

  1. Linux下如何让自己的程序在开机时自动启动
  2. Python:wordcloud.wordcloud()函数的参数解析及其说明
  3. FreeRTOS 中断优先级嵌套错误引发HardFault异常解决
  4. sql sum条件求和_Hive中使用over()实现累积求和和滑动求和
  5. 20211005 Hermite矩阵及几个性质
  6. LoadRunner性能测试-思考时间
  7. 【华为云技术分享】Linux内核源码结构(1)
  8. 报错:error LNK2001:unresolved external symbol _WinMain@16
  9. 各种接口的硬盘在linux中的文件名
  10. 选址(重心法、微分法迭代)
  11. web网页设计期末课程大作业:基于HTML+CSS+JavaScript个人书画作品展示HTML模板(6页)
  12. 集合竞价和连续竞价03
  13. 小草与大树的一分钟演讲
  14. 1024 发福利,送你一份珍藏依旧的 Java,大数据礼包,确定不收藏 ?拒绝白嫖 !
  15. 小鼠心肌细胞培养方法
  16. RecyclerView实现多种布局样式
  17. CentOS 7安装配置vsftp并搭建FTP(一)
  18. Apache报错0x6eec38dc指令引用的0x00000000内存。该内存不能为read。
  19. 关于淘宝店铺运营的一点思考
  20. [爆笑网文]10年假球白练了!----伤心球迷致中国足球队的一封信

热门文章

  1. 二叉树的前序、中序、后序、递归以及非递归遍历
  2. ubuntu安装ROS时遇到的“由于没有公钥,无法验证签名”问题
  3. 敏捷史诗故事是什么_史诗已死。 这是我们应该做的。
  4. 项目管理文档_PPM优课第18期 | 不同项目管理模式“武装”质量管理体系的搭建...
  5. 西安电子科技大学硕士论文latex模板第1章修改为第一章
  6. 蓝海卓越计费管理系统 debug.php_未授权RCE
  7. [翻译]理解Unity的自动内存管理
  8. 获取微博内容的文字以及表情
  9. Latex排版常用数学符号表示方法
  10. 真人语音朗读软件_影视解说视频配音,抖音配音,微课配音,实用免费配音软件,文本朗读,一键文字转语音,媲美真人的配音软件...