股票买卖系列总结

股票买卖系列的题目在面试中还是比较经典的,这里对这一系列做一些简单的总结。

1. 只允许买卖一次

假设股票价格序列为(3, 5, 7, 3, 8, 1)

动态规划。整个过程中的行为选择有3种,买/卖/无操作。

用\(dp[i]\)表示第\(i\)天的行为是”卖出“时,能得到的最大收益。显然,我们固定了卖出的时间,只要在这个时间点之前的时间中选择股票价格比最小的时候买入,就可以确定\(dp[i]\)的值。

所以我们可以遍历价格序列,cur_min不断更新以记录当前时间点之前的股票最低价格,所以\(dp[i] = max(0, prices[i]-cur\_min)\),最后所有dp[i]中的最大值就是只进行一次买卖能得到的最大利润。可以在求\(dp[i]\)的同时用一个变量来记录其最大值。

因为\(dp[i]\)只用到一次,所以没必要开一个数组专门来存储。

class Solution {
public:int maxProfit(vector<int>& prices) {// 只允许最多一次交易 求最大收益// 记录当前最小  cur_min dp[i]表示在第i天卖出的最大收益if(prices.size()<=1) return 0;int cur_min = prices[0], res = 0;for(int i=1; i<prices.size(); i++){res = max(prices[i]-cur_min, res);// dp[i] = prices[i] - cur_min;cur_min = min(cur_min, prices[i]);}return res;}
};

2. 不限制买卖次数

假设股票价格序列为(1, 2, 3, 4, 5)。其实这是一个特殊情况,我们可以在第0天买入,然后在最后一天卖出。此时最大收益就是4。

我们也可以在第0天买入,第一天卖出。第一天买入,第二天卖出。。。这样的结果和上面是一样的,最大收益都是4。

所以,对于比较常规的情况,比如说(7, 6, 3, 4, 5),在第一天和第二天是不能买入的,因为,之后找不到比当前价格更大的数了。另外的话,可以在3的时候买入,4的时候卖出,然后4又买入,5卖出。最后最大收益是2.

class Solution {
public:int maxProfit(vector<int>& prices) {// 不限制股票的买卖次数// 只要是遇到比当前价格更高的就卖掉if(prices.size() <=1) return 0;int buy = INT_MAX, profit = 0;for(int i=0; i<prices.size(); i++){if(prices[i]<=buy) buy = prices[i];else{profit += prices[i]-buy;buy = prices[i];}}return profit;}
};

可以将上面代码进行简化:

class Solution {
public:int maxProfit(vector<int>& prices) {if(prices.size() <=1) return 0;int buy = INT_MAX, profit = 0;for(int i=0; i<prices.size(); i++){if(prices[i] > buy) profit += prices[i] - buy;// 只有当当前价格大于假设买入的价格时,才进行卖出buy = prices[i];// 每次都在当前进行“假设”买入}return profit;}
};

3. 最多只能买卖2次

\(buy1\)表示在第\(i\)天进行第一次买入时可以获得的最大收益
\(buy2\)表示在第\(i\)天进行第二次买入时可以获得的最大收益
\(sell1\)表示在第\(i\)天进行第一次卖出时可以获得的最大收益
\(sell2\)表示在第\(i\)天进行第二次卖出时可以获得的最大收益

class Solution {
public:int maxProfit(vector<int>& prices) {// 最多只能买卖2次 求最大收益// buy1 sell1 buy2 sell2 分别表示当前天如果是第一次买/卖、第二次买/卖时的最大收益int buy1 = INT_MIN, buy2 = INT_MIN, sell1 = 0, sell2 = 0;for(int price:prices){sell2 = max(sell2, buy2+price);buy2 = max(buy2, sell1-price);sell1 = max(sell1, buy1+price);buy1 = max(buy1, -price);}return sell2;}
};

4. 有冷冻期不限制买卖次数

\(buy[i]\)表示第\(i\)天之前最后一次行为是buy时,最大的收益

\(sell[i]\)表示第\(i\)天之前最后一次行为是sell时,最大的收益

\(rest[i]\)表示第\(i\)天之前最后一次行为是冷冻rest时,最大的收益

\(buy[i] = max(buy[i-1], rest[i-1] - prices[i])\),max(第i天冷冻, 第i天是卖出)

\(sell[i] = max(sell[i-1], buy[i-1] + prices[i])\),max(第i天冷冻,第i天是买入)

\(rest[i] = max(rest[i-1], buy[i-1], sell[i-1])\)

class Solution {
public:int maxProfit(vector<int>& prices) {// 有冷冻期 不限制买卖次数 但是卖完股票后有一天的冷冻期才能再接着买int n = prices.size();if(n<=1) return 0;vector<int> buy(n, INT_MIN), sell(n, INT_MIN), rest(n, INT_MIN);buy[0] = -prices[0];sell[0] = 0;rest[0] = 0;for(int i=1; i<n; i++){buy[i] = max(buy[i-1], rest[i-1]-prices[i]);sell[i] = max(sell[i-1], buy[i-1]+prices[i]);rest[i] = max(rest[i-1], max(buy[i-1], sell[i-1]));}return max(buy[n-1], max(sell[n-1], rest[n-1]));}
};

转载于:https://www.cnblogs.com/Elaine-DWL/p/11202859.html

【leetcode】股票买卖系列总结相关推荐

  1. 【LeetCode股票买卖系列:714. 买卖股票的最佳时机含手续费 | 暴力递归=>记忆化搜索=>动态规划】

  2. 动态规划之股票买卖系列问题

    文章目录 一.股票买卖系列问题 二.leetcode例题讲解股票买卖系列问题 121. 买卖股票的最佳时机 122. 买卖股票的最佳时机 II 123. 买卖股票的最佳时机 III 188. 买卖股票 ...

  3. leetcode17. 电话号码的字母组合--每天刷一道leetcode算法系列!

    作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...

  4. 八十一、Python | Leetcode 二叉树系列(下篇)

    @Author:Runsen @Date:2020/7/6 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  5. 七十四、Python | Leetcode数字系列(下篇)

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  6. 七十三、Python | Leetcode数字系列(上篇)

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  7. 七十二、Python | Leetcode字符串系列(下篇)

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  8. 七十一、Python | Leetcode字符串系列(上篇)

    @Author:Runsen @Date:2020/7/3 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  9. LeetCode 股票买卖问题

    LeetCode 股票买卖问题 文章目录 LeetCode 股票买卖问题 一.问题描述 **二. 穷举框架** **三. 状态转移框架** **四.解题** `第一题`:`K = 1` `第⼆题`, ...

最新文章

  1. ASP.NET MVC进阶三
  2. 003_Spring Data JPA分页和排序查询
  3. 安卓MP3播放器开发实例(3)之进度条和歌词更新的实现
  4. docker --- 使用docker-compose.yml生成redis,并连接redis-cli
  5. CentOS5.11安装Mac桌面主题
  6. selenium 等待页面加载完成
  7. 【软件质量】软件可移植性
  8. 马氏距离详解(数学原理、适用场景、应用示例代码)
  9. yum 安装oraclejdk_kubernetes-16:制作oraclejdk镜像
  10. c语言转图形化,「分享」C语言如何编写图形界面
  11. 【转载】asp.net core 入门
  12. 英伟达早期显卡驱动下载
  13. xp系统 共享文件夹服务器,WinXP如何共享文件夹?共享文件夹的方法
  14. Unity资源管理(四)-AssetBundle使用模式
  15. 程序员面试金典——解题总结: 9.18高难度题 18.5有个内含单词的超大文本文件,给定任意两个单词,找出在这个文件中这两个单词的最短距离
  16. 顶层const和底层const的含义和区别
  17. OpenCV从摄像头中检测人脸
  18. 什么是MyBatis?怎么操作MyBatis?
  19. R语言:R2OpenBUGS
  20. iOS 生成自定义位数随机数

热门文章

  1. 8.ActionContext类与Servlet API解耦的访问方式
  2. webpack最简单的入门教程里bundle.js之运行单步调试的原理解析
  3. QT入门安装篇+helloworld(辛酸血泪)
  4. MWeb 的基本使用
  5. Day18 (一)类的加载器
  6. C++ 复制构造函数
  7. Excel生成报表之解决方案--设置单个单元格格式
  8. 单点登陆框架CAS的研究
  9. Andriod开发中正确引入jar包的方式
  10. android 验证码