给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

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

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

链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock

方法一:分治 O(nlgn)

要求最大利润,即p[j]-p[i]最大并且i < j. 将区间分为[l,mid-1],[mid+1,r]两部分。则有三种情况。

  1. 买入的股票和卖出的股票都在区间[l,mid-1]完成。
  2. 买入的股票和卖出的股票都在区间[mid+1,r]完成。
  3. 区间穿过mid,在左区间买入股票,在右区间卖出股票。

对于情况1和2,递归完成。
对于情况3,已知情况是区间穿过mid,即mid在区间里。我们可以从mid开始向左遍历找到最小的p[i],从mid开始向右遍历找到最大的p[j],p[j]-p[i]就是[i…mid…j]的最大利润。
最后对三种情况取最大值。
下面上代码。

class Solution {public:int Merge(vector<int>& prices, int l, int r){if(l >= r){return 0;}int mid = l+r>>1;int x1 = Merge(prices,l,mid-1);int x2 = Merge(prices,mid+1,r);int l_min = prices[mid], r_max = prices[mid];for(int i = mid;i >= 0;i--)l_min = min(prices[i], l_min);for(int i = mid;i <= r;i++)r_max = max(r_max, prices[i]);int x3 = r_max - l_min;return max(max(x1,x2), x3);}int maxProfit(vector<int>& prices) {int n = prices.size();return Merge(prices,0,n-1);}
};

方法二:dp O(n)

要求最大利润,即p[j]-p[i]最大并且i < j. 如果我们能知道前j个元素中的最小值,就可以找到买股票的起点。因此令dp[i]表示前i个元素中的最小值,可以得到这样的状态转移方程:
dp[0] = p[0],dp[i] = min(p[i], dp[i-1]).
那么a[i] - dp[i]就代表着前i个元素中的最大利润。我们枚举i,找到最大的i使得a[i]-dp[i]最大即可。
代码如下:

class Solution {public:int maxProfit(vector<int>& prices) {vector<int> dp(prices.size(),0);if(prices.size() == 0) return 0;int n = dp.size(), ans = 0;dp[0] = prices[0];for(int i = 1;i < n;i++){dp[i] = min(prices[i], dp[i-1]);ans = max(ans, prices[i]-dp[i]);}return ans;}
};

dp空间优化:

对于状态转移方程中的dp[i-1]的值,我们可以直接用一个Min代替数组的滚动。
下面上代码:

class Solution {public:int maxProfit(vector<int>& prices) {if(prices.size() == 0) return 0;int n = prices.size(), ans = 0, Min = prices[0];for(int i = 1;i < n;i++){Min = min(prices[i], Min);ans = max(ans, prices[i]-Min);}return ans;}
};

买卖股票的最佳时机(分治,dp)相关推荐

  1. 123. 买卖股票的最佳时机 III ( 三维dp )

    LeetCode:123. 买卖股票的最佳时机 III 之前的含手续费定义了两个状态(持股与不持股), 含冷冻期定义了三个状态(持股, 不持股冷冻期, 不持股非冷冻期), 都是二维数组. 本题除了持股 ...

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

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

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

    前言 大家好,我是大赛哥,好久不见,天天想念! 最近梳理高频动态规划问题,股票问题当然是非常经典的动态规划问题,并且整个系列有好几道题,这里我整理了6道股票系列的经典问题分享给大家,咱们今天聊聊买卖股 ...

  4. 买卖股票的最佳时机含手续费

    相对于动态规划:122.买卖股票的最佳时机II,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的. 唯一差别在于递推公式部分 dp[i][0] 表示第i天持有股票所省最多现金. dp ...

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

    思路 这道题目可以说是动态规划:123.买卖股票的最佳时机III的进阶版,这里要求至多有k次交易. 确定dp数组以及下标的含义 在动态规划:123.买卖股票的最佳时机III中,我是定义了一个二维dp数 ...

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

    思路 这道题目相对 121.买卖股票的最佳时机 和 122.买卖股票的最佳时机II 难了不少. 关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖. 确定dp数组以及下标的含义 一 ...

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

    思路 本题和121. 买卖股票的最佳时机的唯一区别本题股票可以买卖多次了(注意只有一只股票,所以再次购买前要出售掉之前的股票) 这里重申一下dp数组的含义: dp[i][0] 表示第i天持有股票所得现 ...

  8. LeetCode 121:买卖股票的最佳时机 思考分析

    题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润. 注意:你不能在买入股票 ...

  9. LeetCode 188. 买卖股票的最佳时机 IV(动态规划)

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

最新文章

  1. 记录一下vlfeat视觉库配置
  2. mysql执行计划extra为null_MySQL执行计划extra解析
  3. 约瑟夫环算法c语言,约瑟夫环的c语言实现(代码已实现)
  4. slider使用TickPlacement获得游标效果
  5. SharePoint Designer 2007发布WorkFlow的小bug
  6. ZJOI2007时态同步
  7. openstack configure
  8. 陈纪修老师《数学分析》 第11章:欧式空间上的极限和连续 笔记
  9. 高数 吉米多维奇 785
  10. 服务器2012怎么安装无线网卡驱动,如何安装usb无线网卡驱动,教您如何安装电脑usb驱动...
  11. VS2003安装包和方法
  12. java视频会议系统 mcu_视频会议系统必须要用MCU吗
  13. 有助于睡眠的产品,失眠一定要知道的几样东西
  14. 文档已完成加载后执行document write整个 HTML 页面将被覆盖
  15. leaflet实现风场动态粒子效果
  16. 【AI学习总结】均方误差(Mean Square Error,MSE)与交叉熵(Cross Entropy,CE)损失函数
  17. Android Google Services Framework Google Play
  18. 如果同步块内的线程抛出异常会发生什么?
  19. 交易所要变天?去中心化交易所崛起,蚕食用户,抢夺流量
  20. 【解决方案】RTMP推流协议视频智能分析/直播点播/人脸识别平台EasyDSS打造智能多媒体展厅解决方案

热门文章

  1. 浪潮信息服务器发展趋势,浪潮:从山大高性能集群看HPC发展趋势
  2. 如何将文字转换成语音?分享两款实用软件
  3. OC_Fundation框架定义的一些结构的基本使用
  4. 图像位深度 8位 16位 24位 32位区别对比 RGB 真彩色 基本概念:(大小,深度,通道)位深度数据类型转换原理 Mat数据读取(opencv里的imread)
  5. JAVA天眼大型分布式跟踪系统
  6. Google收购免费问答网站Aardvark
  7. 使用itextpdf实现截取pdf文档第几页到第几页,进行分片
  8. 手把手教你不用写前端,手撸一个纯JAVA后台系统
  9. ROS系统中launch文件无法启动
  10. 各向异性滤波算法+数学模型分析