问题

给定一个数组,第i个元素表示第i天股票的价格,可执行多次“买一次卖一次”,每次执行完(卖出后)需要小费,求最大利润

Input: prices = [1, 3, 2, 8, 4, 9], fee = 2

Output: 8

Explanation: ((8 - 1) - 2) + ((9 - 4) - 2) = 8

思路和代码

在某天交易(或选择不操作)之后,有两个状态,要么手有股票,要么手中没有股票,我们用两个状态数组来表示。hava_stock表示有股票,no_stock表示没有股票。

have_stock[i]表示第i天结束后(此时手中有股票)最大利润。

no_stock[i]表示第i天结束后(此时手中没股票)的最大利润。

如果当天操作结束后,你手头没有股票的话,那么你:要么是今天卖了股票(昨天是有股票的),要么是保持了昨天的状态,只需要在这两者取最大即可。no_stock[i] = max(have_stock[i-1]+prices[i]-fee, no_stock[i-1])。

如果当天操作结束后,你手头有股票的话,那么你:要么是今天买了股票(昨天是没有股票的),要么是保持了昨天的状态,只需要在这两者取最大即可。have_stock[i] = max(no_stock[i-1]-prices[i], have_stock[i-1])。

返回最后一天的no_stock即可,因为完成交易获得最大利润时,手头肯定是没有股票的。

时间复杂度O(n),空间复杂度O(n)

class Solution(object):
def maxProfit(self, prices, fee):
"""
:type prices: List[int]
:type fee: int
:rtype: int
"""
no_stock = [0]*len(prices)
have_stock = [0]*len(prices)
have_stock = -prices[0]
for i in range(1,len(prices)):
no_stock[i] = max(have_stock[i-1]+prices[i]-fee, no_stock[i-1])
have_stock[i] = max(no_stock[i-1]-prices[i], have_stock[i-1])
return no_stock[len(prices)-1]

优化

由于两个dp数组中状态都取决于前一天,可以进行优化,省去dp数组开销。

对于no_stock的max计算,直接去掉数组索引,计算前的变量have_stock[i-1]和no_stock[i-1]表示前一天的,直接写成have_stock和no_stock即可,计算后的变量no_stock[i]表示今天的,写成no_stock即可。

对于have_stock的max计算,have_stock[i-1]也可以直接写成have_stock表示前一天的,而no_stock[i-1]不能写成no_stock,因为在上一步计算(no_stock的计算中可能覆盖了),所以可以用一个tmp在no_stock计算之前暂存起来。

tmp = no_stock
no_stock = max(have_stock+prices[i]-fee, no_stock)
have_stock = max(tmp-prices[i], have_stock)

事实上这个临时变量也可以省去。考虑no_stock的max操作,当no_stock较大时当然不需要用tmp来暂存前一天的no_stock,因为前一天跟今天的一样。而have_stock+prices[i]-fee较大时可以得到have_stock > no_stock - prices[i],此时have_stock的max计算会直接取到have_stock,不会用到no_stock,所以不用担心no_stock被改变后影响have_stock的max计算。

时间复杂度O(n),空间复杂度O(1)

class Solution(object):
def maxProfit(self, prices, fee):
"""
:type prices: List[int]
:type fee: int
:rtype: int
"""
no_stock = 0
have_stock = -prices[0]
for i in range(1,len(prices)):
no_stock = max(have_stock+prices[i]-fee, no_stock)
have_stock = max(have_stock, no_stock-prices[i])
return no_stock

类似题目

121. Best Time to Buy and Sell Stock

最新文章

  1. sqlserver权限体系(下)
  2. Cenos(6.6/7.1)下从源码安装Python+Django+uwsgi+nginx到写nginx的环境部署(一)
  3. IE Unknown runtime error
  4. Python2.x与Python3.x的区别
  5. het smooth 组装高杂合度二倍体基因组前期数据处理
  6. ASP.NET导出excel表方法汇总
  7. Windows下Redis的安装使用[转]
  8. ImageView建立selector在录音中遇到的小问题及解决方案
  9. ps -ef |grep 输出的具体含义
  10. org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named '__frch_lableId_0' in 'class com.cd.entity.Page'
  11. SQL学习之查询
  12. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 对外不要提供Delete方法加强软件的安全性
  13. Integer To Roman leetcode java
  14. Kafka Stream
  15. #151: 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-x
  16. HashMap从源码分析数据结构
  17. 基于prometheus监控k8s集群
  18. Mybatis常见面试题 三
  19. Nginx_status显示结果详解
  20. 理解Canvas原理

热门文章

  1. 【转】Native Thread for Win32 A- Create Thread(通俗易懂,非常好)
  2. myForm.js
  3. [UIImage _isCached]: message sent to deallocated instance
  4. 更改hadoop native库文件后datanode故障
  5. 2D绘图引擎比较
  6. Eclipse 安装更多版本SDK
  7. Node.js 搭建Web
  8. HDU_5536_Chip Factory
  9. [已解决]ubuntu下chrome和firefox输入框内无法快捷键全选
  10. 【我的Android进阶之旅】快速创建和根据不同的版本类型(Dev、Beta、Release)发布Android 开发库到Maven私服