好想实习工作
好想读博
好想广隆蛋挞王的蛋挞
好想。。。
题目描述:
给定一个整数数组 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.
思路解析:
这一题是非常典型的动态规划题目,其实前面有几道与之相关的股票计算的题目了,最像的应该就是第122题-买卖股票的最佳时机 II 了。我的解析在这篇文章里。我当时采用的是贪心法,因为每次股票买进卖出不需要手续费,所以只要每次买进的股票的价格低于卖出的价格,我就可以保证此次交易是赚钱的。对于本题而言考虑到手续费,所以就不能直接用贪心算法了。
一般的,我们知道,能用贪心算法解决的题目基本上都是可以用动态规划解决。本题也是如此,动态规划的问题,我们只需要找到动态转移方程即可。首先,我们定义两个数组,分别记录每个时间点的最大利润(cash)以及每个时间点买入股票后的余额(hold)。那么cash[-1]就是我们想要的结果。
这种思想其实也很好理解,最大利润的计算步骤无非就是找到多段最小股票价格和最大股票价格的差值,每一段区间的最小值以及最大值是不一样的,所以我们肯定是要用hold来记录最小值的,另外我们就是用cash来记录最大差值。递归方程的话直接见代码吧,特别简单,就两行。
代码如下:
class Solution(object):
def maxProfit(self, prices, fee):
"""
动态回归问题;分别定义最大现金和当前购入股票的数组
:type prices: List[int]
:type fee: int
:rtype: int
"""
cash, hold = [0]*len(prices),[-prices[0]]*len(prices)
for i in range(1, len(prices)):
cash[i] = max(cash[i-1], hold[i-1]+prices[i]-fee)
hold[i] = max(hold[i-1], cash[i]-prices[i])
return cash[-1]
if __name__ == "__main__":
prices = [1, 3, 2, 8, 4, 9]
fee = 2
max_profit = Solution().maxProfit(prices, fee)
print(max_profit)
执行效率还算中等吧,在50%左右。