给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每次交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

示例 1:

输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润:
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
注意:

0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.

来源:力扣(LeetCode)

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

方法:动态规划

我们维护两个变量 cash 和 hold,前者表示当我们不持有股票时的最大利润,后者表示当我们持有股票时的最大利润。

在第 i 天时,我们需要根据第 i−1 天的状态来更新 cash 和 hold 的值。对于 cash,我们可以保持不变,或者将手上的股票卖出,状态转移方程为

cash = max(cash, hold + prices[i] - fee)

对于 hold,我们可以保持不变,或者买入这一天的股票,状态转移方程为

hold = max(hold, cash - prices[i])

在计算这两个状态转移方程时,我们可以不使用临时变量来存储第 i−1 天 cash 和 hold 的值,而是可以先计算 cash 再计算 hold,原因是在同一天卖出再买入(亏了一笔手续费)一定不会比不进行任何操作好。

python

class Solution(object):
def maxProfit(self, prices, fee):
cash, hold = 0, -prices[0]
for i in range(1, len(prices)):
cash = max(cash, hold + prices[i] - fee)
hold = max(hold, cash - prices[i])
return cash

java

class Solution {
public int maxProfit(int[] prices, int fee) {
int cash = 0, hold = -prices[0];
for (int i = 1; i < prices.length; i++) {
cash = Math.max(cash, hold + prices[i] - fee);
hold = Math.max(hold, cash - prices[i]);
}
return cash;
}
}

复杂度分析

时间复杂度:O(n),其中 n 是 prices 数组的长度。

空间复杂度:O(1)。

解法一:

class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
vector<int> sold(prices.size(), 0), hold = sold;
hold[0] = -prices[0];
for (int i = 1; i < prices.size(); ++i) {
sold[i] = max(sold[i - 1], hold[i - 1] + prices[i] - fee);
hold[i] = max(hold[i - 1], sold[i - 1] - prices[i]);
}
return sold.back();
}
};

我们发现不管是卖出还是保留,第i天到利润只跟第i-1天有关系,所以我们可以优化空间,用两个变量来表示当前的卖出和保留的利润,更新方法和上面的基本相同,就是开始要保存sold的值,不然sold先更新后,再更新hold时就没能使用更新前的值了,参见代码如下:

解法二:

class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int sold = 0, hold = -prices[0];
for (int price : prices) {
int t = sold;
sold = max(sold, hold + price - fee);
hold = max(hold, t - price);
}
return sold;
}
};

最新文章

  1. C++语言-07-异常处理和信号处理
  2. bash: 避免命令重复执行的简单脚本
  3. 关于try...catch...finally中return的疑惑
  4. jsp自定义标签分页
  5. ThinkPHP3.1新特性:命名范围
  6. main函数的参数
  7. MySql移植到嵌入式Linux平台
  8. hdu4171 Paper Route 树的性质+DFS
  9. CCF-201503-2-数字排序
  10. 测试CentOS-7-x86_64-Minimal-1708.iso这种光盘安装效果
  11. 第 16 章 C 预处理器和 C 库(可变参数:stdarg.h)
  12. MyEclipse常用设置和快捷键
  13. Makefile introduction (very old presentation)
  14. ES6必知必会 (四)—— Symbol、Set和Map
  15. WP8.1 控件默认字体颜色 配置文件位置
  16. HDU 2138 How many prime numbers (判素数,米勒拉宾算法)
  17. SAP 前端技术的演化史简介
  18. TQ2440系统介绍入门 、linux系统目录结构
  19. Android开发 获取当前activity的屏幕截图(转载)
  20. 阿里云环境搭建CDN内容分发

热门文章

  1. BeginInvoke之前检测句柄
  2. 一条 SQL 在 Apache Spark 之旅
  3. springboot - 映射HTTP Response Status Codes 到 静态 HTML页面
  4. POJ 1426:Find The Multiple
  5. tomcat迁移到weblogic的几个问题
  6. Spring(5) -(14) pointcut 语法
  7. [转自官方文档] Django——render()
  8. Codeforces 433C #248_div1_A 中位数的应用
  9. PrepareStatement对象进行批处理的典型步骤顺序
  10. 吴裕雄--天生自然Django框架开发笔记:Django 模板