问题

给定一个数组,第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

714. Best Time to Buy and Sell Stock with Transaction Fee的更多相关文章

  1. Week 7 - 714. Best Time to Buy and Sell Stock with Transaction Fee & 718. Maximum Length of Repeated Subarray

    714. Best Time to Buy and Sell Stock with Transaction Fee - Medium Your are given an array of intege ...

  2. 714. Best Time to Buy and Sell Stock with Transaction Fee有交易费的买卖股票

    [抄题]: Your are given an array of integers prices, for which the i-th element is the price of a given ...

  3. [LeetCode] 714. Best Time to Buy and Sell Stock with Transaction Fee 买卖股票的最佳时间有交易费

    Your are given an array of integers prices, for which the i-th element is the price of a given stock ...

  4. 【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee

    题目如下: Your are given an array of integers prices, for which the i-th element is the price of a given ...

  5. 【LeetCode】714. Best Time to Buy and Sell Stock with Transaction Fee 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...

  6. Leetcode之动态规划(DP)专题-714. 买卖股票的最佳时机含手续费(Best Time to Buy and Sell Stock with Transaction Fee)

    Leetcode之动态规划(DP)专题-714. 买卖股票的最佳时机含手续费(Best Time to Buy and Sell Stock with Transaction Fee) 股票问题: 1 ...

  7. [LeetCode] Best Time to Buy and Sell Stock with Transaction Fee 买股票的最佳时间含交易费

    Your are given an array of integers prices, for which the i-th element is the price of a given stock ...

  8. [Swift]LeetCode714. 买卖股票的最佳时机含手续费 | Best Time to Buy and Sell Stock with Transaction Fee

    Your are given an array of integers prices, for which the i-th element is the price of a given stock ...

  9. LeetCode-714.Best Time to Buy and Sell Stock with Transaction Fee

    Your are given an array of integers prices, for which the i-th element is the price of a given stock ...

随机推荐

  1. JQuery------实现鼠标摁下抬起时div背景色改变

    作用:使用自定义一个按钮 代码: <div class = 'btn'>按钮</div> $(".btn").mousedown(function () { ...

  2. IOS 程序内部切换语言 的一种方法

    本文转载至  http://www.cnblogs.com/wuyijibei/archive/2013/08/01/3230468.html 1: 首先, 所有的语言资源还是需要和现在的i18n方法 ...

  3. C++中的自动存储、静态存储和动态存储

    根据用于分配内存的方法,C++中有3中管理数据内存的方式:自动存储.静态存储和动态存储(有时也叫做自由存储空间或堆).在存在是间的长短方面,以这三种方式分配的数据对象各不相同.下面简要介绍这三种类型( ...

  4. 《C++ Primer Plus》学习笔记0

    Hello,World! 本书版本:<C++ Primer Plus(第6版)中文版>C++是在C语言基础上开发的一种集面向对象编程.泛型编程和过程化编程于一体的编程语言,是C语言的超集. ...

  5. 在 Linux 上管理加密密钥的最佳体验

    导读 存储 SSH 的加密秘钥和记住密码一直是一个让人头疼的问题.但是不幸的是,在当前这个充满了恶意黑客和攻击的世界中,基本的安全预防是必不可少的.对于许多普通用户来说,大多数人只能是记住密码,也可能 ...

  6. ORA-28000: the account is locked

    1.用system账号登录 2.执行一下sql: ALTER USER username ACCOUNT UNLOCK; 此处username 可能为scott或者你要解锁的用户名. ........ ...

  7. nginx的简单使用和使用nginx在windows上搭建tomcat集群

    nginx是一款轻量级的web服务器,常用的作用为服务器/反向代理服务器以及电子邮件(IMAP/POP3)代理服务器 1.为什么我们要使用Nginx? 反向代理: 反向代理(Reverse Proxy ...

  8. 170405、java版MD5工具类

    package com.rick.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmExce ...

  9. Hadoop 启动脚本分析与实战经验

    start-all.sh脚本现在已经废弃,推荐使用start-dfs.sh和start-yarn.sh分别启动HDFS和YARN. 在新一代的Hadoop里面HDFS称为了统一存储的平台,而YARN成 ...

  10. Struts2的OGNL的用法

    1 <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1 ...