买卖股票的最佳时机(分治,dp)
给定一个数组,它的第 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]两部分。则有三种情况。
- 买入的股票和卖出的股票都在区间[l,mid-1]完成。
- 买入的股票和卖出的股票都在区间[mid+1,r]完成。
- 区间穿过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)相关推荐
- 123. 买卖股票的最佳时机 III ( 三维dp )
LeetCode:123. 买卖股票的最佳时机 III 之前的含手续费定义了两个状态(持股与不持股), 含冷冻期定义了三个状态(持股, 不持股冷冻期, 不持股非冷冻期), 都是二维数组. 本题除了持股 ...
- 【dp】买卖股票的最佳时机系列题目
文章目录 121. 买卖股票的最佳时机 122. 买卖股票的最佳时机 II 309. 最佳买卖股票时机含冷冻期 123. 买卖股票的最佳时机 III 188. 买卖股票的最佳时机 IV 121. 买卖 ...
- 聊聊买卖股票的最佳时机
前言 大家好,我是大赛哥,好久不见,天天想念! 最近梳理高频动态规划问题,股票问题当然是非常经典的动态规划问题,并且整个系列有好几道题,这里我整理了6道股票系列的经典问题分享给大家,咱们今天聊聊买卖股 ...
- 买卖股票的最佳时机含手续费
相对于动态规划:122.买卖股票的最佳时机II,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的. 唯一差别在于递推公式部分 dp[i][0] 表示第i天持有股票所省最多现金. dp ...
- 买卖股票的最佳时机IV
思路 这道题目可以说是动态规划:123.买卖股票的最佳时机III的进阶版,这里要求至多有k次交易. 确定dp数组以及下标的含义 在动态规划:123.买卖股票的最佳时机III中,我是定义了一个二维dp数 ...
- 买卖股票的最佳时机III
思路 这道题目相对 121.买卖股票的最佳时机 和 122.买卖股票的最佳时机II 难了不少. 关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖. 确定dp数组以及下标的含义 一 ...
- 买卖股票的最佳时机II
思路 本题和121. 买卖股票的最佳时机的唯一区别本题股票可以买卖多次了(注意只有一只股票,所以再次购买前要出售掉之前的股票) 这里重申一下dp数组的含义: dp[i][0] 表示第i天持有股票所得现 ...
- LeetCode 121:买卖股票的最佳时机 思考分析
题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润. 注意:你不能在买入股票 ...
- LeetCode 188. 买卖股票的最佳时机 IV(动态规划)
1. 题目 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多笔交易(你必须在再次购买 ...
最新文章
- 记录一下vlfeat视觉库配置
- mysql执行计划extra为null_MySQL执行计划extra解析
- 约瑟夫环算法c语言,约瑟夫环的c语言实现(代码已实现)
- slider使用TickPlacement获得游标效果
- SharePoint Designer 2007发布WorkFlow的小bug
- ZJOI2007时态同步
- openstack configure
- 陈纪修老师《数学分析》 第11章:欧式空间上的极限和连续 笔记
- 高数 吉米多维奇 785
- 服务器2012怎么安装无线网卡驱动,如何安装usb无线网卡驱动,教您如何安装电脑usb驱动...
- VS2003安装包和方法
- java视频会议系统 mcu_视频会议系统必须要用MCU吗
- 有助于睡眠的产品,失眠一定要知道的几样东西
- 文档已完成加载后执行document write整个 HTML 页面将被覆盖
- leaflet实现风场动态粒子效果
- 【AI学习总结】均方误差(Mean Square Error,MSE)与交叉熵(Cross Entropy,CE)损失函数
- Android Google Services Framework Google Play
- 如果同步块内的线程抛出异常会发生什么?
- 交易所要变天?去中心化交易所崛起,蚕食用户,抢夺流量
- 【解决方案】RTMP推流协议视频智能分析/直播点播/人脸识别平台EasyDSS打造智能多媒体展厅解决方案
热门文章
- 浪潮信息服务器发展趋势,浪潮:从山大高性能集群看HPC发展趋势
- 如何将文字转换成语音?分享两款实用软件
- OC_Fundation框架定义的一些结构的基本使用
- 图像位深度 8位 16位 24位 32位区别对比 RGB 真彩色 基本概念:(大小,深度,通道)位深度数据类型转换原理 Mat数据读取(opencv里的imread)
- JAVA天眼大型分布式跟踪系统
- Google收购免费问答网站Aardvark
- 使用itextpdf实现截取pdf文档第几页到第几页,进行分片
- 手把手教你不用写前端,手撸一个纯JAVA后台系统
- ROS系统中launch文件无法启动
- 各向异性滤波算法+数学模型分析