原文地址:https://www.namidame.tech/brokes-max-profit.html

1. 问题描述

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

  • 示例 1:
    输入: [7,1,5,3,6,4]
    输出: 7
    解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
    随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

  • 示例 2:
    输入: [1,2,3,4,5]
    输出: 4
    解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
    注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
    因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

  • 示例 3:
    输入: [7,6,4,3,1]
    输出: 0
    解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

  • 提示:
    1 <= prices.length <= 3 * 10 ^ 4
    0 <= prices[i] <= 10 ^ 4

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2zsx1/

2. 问题分析

每当遇到算法问题,我们都要有一个最基本的信念,就是就算用最笨的方法,也要先把问题解决掉先(笑)针对股票买卖问题,题目已经说明了数组的项数是万级的,对这种大量数据的处理特别要注意不能采用时间复杂度过高的算法,复杂度o(n^2)已经是不能接受的了,如果采用
o(n^2)算法本题的运算量会到达万万级也就是亿级。。。如果数据再多10倍那么运算时间将会多100倍,这是不可接受的,至少也要用o(n)复杂度的算法来解决这种问题。

3. 普通算法

可以先采用普通的算法来实现,也就是死算。。针对每一个价格,找到下一个可以实现最大利润的价格,然后作买卖,再针对下一个价格重复执行这个步骤,最终会得出最高利润。因为只需要遍历一遍整个数组就可以完成,循环次数最多也只是n次,所以这种算法的时间复杂度为o(n)。

#include<vector>
using namespace std;
// 普通实现
int maxProfit(vector<int>& prices) {if(prices.size() == 0 || prices.size() == 1){return 0;}int pre = 0, next = 1;int sum = 0;    // 总收益int curMax = 0; // 当前时间段最大收益while(next < prices.size()){int diff = prices[next] - prices[pre];if(diff > curMax){curMax = diff;++next;}else if(diff < curMax)   // 沽{sum += curMax;curMax = 0;pre = next;++next;}else{++next;}if(next == prices.size()){sum += curMax;}}return sum;
}int main()
{int a[6] = {7,1,5,3,6,4};vector<int>prices(a, a+6);int max = maxProfit(prices);cout << max << endl;    // 7
}

4. 贪心算法

我们可以针对普通的算法作一点优化,现在想象我们是一个贪心的投资者,我们不想像普通算法那样,一直找到后面一个价格的极高点时再卖出,而是只着眼于眼前的利益,每当我发现后面的某一天的价格比今天的价格高就在今天买入那一天卖出,也就是一旦有利润就先赚了再说,这种方法即贪心算法。可以看到无论是贪心算法还是普通算法,得出的最大利润是一样的。

#include<iostream>
#include<vector>
using namespace std;// 贪心算法实现
int maxProfit(vector<int>& prices) {if(prices.size() <= 1){return 0;}int sum = 0;for(int i = 1; i < prices.size(); i++){sum += max(prices[i] - prices[i - 1], 0);}return sum;
}int main()
{int a[6] = {7,1,5,3,6,4};vector<int>prices(a, a+6);int max = maxProfit(prices);cout << max << endl;    // 7
}

5. 动态规划

题目给定了一组股票价格,要求我们给出每一天的买卖操作,并且求得这一组操作得到的最终的最大利润,这种问题属于多阶段决策问题。每一天都需要我们根据当天的股票价格和之前的买卖情况作出决策,每一天所作的决策都会影响到后面的收益,这种能够分成多个阶段而且每个阶段都要求我们根据当前的情况作出决策以求得最优解的问题,可以应用动态规划的方法来解决。

  • 每一天的操作都会带来当天的收益,而每一天的操作只可能是持有或者不持有,假设我们用0表示不持有,用1表示持有,那么第i天不持有时的收益可记为dp[i][0],第i天持有时的收益可记为dp[i][1]。
  • 根据数据我们可以先得到动态规划的初始状态:
    dp[0][0] = 0;           // 第0天不持有时,收益为0dp[0][1] = -prices[0]   // 第0天持有时,要支出当天价格
  • 然后我们便可以根据价格数据一天一天地记录下当天所有操作所产生的利润数据:

    • 第i天不持有时,若前一天持有,即第i天卖了股票,此时第i天的收益为dp[i-1][1] + prices[i]
    • 第i天不持有时,若前一天也不持有,那么收益和之前相等dp[i-1][0]
    • 第i天持有时,若前一天也持有,那么收益和之前相等dp[i-1][1]
    • 第i天持有时,若前一天不持有,即第i天买入了股票,此时第i天的收益为dp[i-1][0]-prices[i]
      然后每一天都比较前一天持有或不持有时的收益,取其较大者便是当天达到最大收益的操作
  • 最后获得的最大收益,即最后一天不持有股票时的收益
#include<iostream>
#include<vector>
using namespace std;// 动态规划实现
int maxProfit(vector<int>& prices) {if(prices.size() <= 1){return 0;}int dp[prices.size()][2];dp[0][0] = 0;dp[0][1] = -prices[0];for(int i = 1; i < prices.size(); i++){dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);}return dp[prices.size() - 1][0];
}int main()
{int a[6] = {7,1,5,3,6,4};vector<int>prices(a, a+6);int max = maxProfit(prices);cout << max << endl;    // 7
}

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者: 你很德布罗意
邮箱: namidame@sina.cn
博客地址: https://www.namidame.tech/
原文地址: http://www.namidame.tech/brokes-max-profit.html

【转载】求买卖股票的最大利润相关推荐

  1. JavaScript实现找出买卖股票的最大利润算法(附完整源码)

    JavaScript实现找出买卖股票的最大利润算法(附完整源码) dpBestTimeToBuySellStocks.js完整源代码 dpBestTimeToBuySellStocks.test.js ...

  2. JAVA数组——买卖股票的最大利润问题

    问题描述:给定一个数据a,数组中的每个元素表示对应下标的股票价格. 如int a[5] = [3,5,7,3,6]表示股票在五天内的价格分别是3,5,7,3,6.请设计算法获取买卖股票的最大利润,并给 ...

  3. 买卖股票的最大利润II——动态规划、贪心

    题目描述: 给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意: ...

  4. 小白学算法:买卖股票的最佳时机!

    作者 | 王磊 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) 本文已收录至 Github<小白学算法>系列:https://gith ...

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

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

  6. LintCode领扣算法问题答案:150. 买卖股票的最佳时机 II

    150. 买卖股票的最佳时机 II 描述 给定一个数组 prices 表示一支股票每天的价格. 你可以完成任意次数的交易, 不过你不能同时参与多个交易 (也就是说, 如果你已经持有这支股票, 在再次购 ...

  7. 力扣leetcode之Java刷题121买卖股票的最佳时机

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

  8. 《LeetCode力扣练习》第121题 买卖股票的最佳时机 Java

    <LeetCode力扣练习>第121题 买卖股票的最佳时机 Java 一.资源 题目: 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价 ...

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

    买卖股票的最佳时机IV 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多笔交易(你必 ...

最新文章

  1. CSS中的id选择器和class选择器简单介绍
  2. 判断一个点是否在RotatedRect中
  3. Netbackup Status code 6解决思路
  4. ORA-01658: 无法为表空间space中的段创建 INITIAL
  5. window部署DM8的DEM系统
  6. 无忧计算机c语言二级题库,干货for计算机等级考试题库:二级C语言试题
  7. 【原】jQuery编写插件
  8. 面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?
  9. Keras的基本使用(1)--创建,编译,训练模型
  10. 生产环境sql语句调优实战第三篇
  11. 孙忠的面向对象第二次作业
  12. hrm系统源码php,开源HRM源码系统下载
  13. 三国志战略版:今天你打铁了吗?货布商店大解析
  14. PC能登录微信,但是不能访问网页/代理服务器没有响应
  15. python 病毒 基因_#Python#提取基因对应的蛋白质名
  16. python可视化图表和excel的区别_Excel的数据可视化和Python的有什么不同?
  17. shell脚本下载小猪佩奇中文版全集mp3
  18. bind()方法实现
  19. 用css画一个原型里有一个对号或者叉叉的图标
  20. 2016 苹果全球开发者大会(WWDC)

热门文章

  1. DNS解析全过程及原理
  2. MegaCli 工具安装使用
  3. python三维建模需要用到哪些知识_三维建模教学大纲
  4. 网络文件共享|磁盘映射
  5. 《活着》读后感 -- 一个活在悲剧中的人为什么要继续活下去
  6. mysql 返回 pair_【原创】MySQL Proxy中socketpair的使用
  7. 使Bootstrap选项卡与砌体一起发挥作用
  8. 剑指Offer46——把数字翻译成字符串
  9. 新手小白如何租用GPU云服务器跑深度学习
  10. MyFFmpeg-我的音视频练习app