买卖股票的最佳时机Ⅲ
题目描述:
解题思路:
这道题跟前两个买卖股票的题目比较更加的难,难就难在这里限制了你只能交易两次。我一开始的想法是类似买卖股票Ⅱ的一个方法,把差值求出来然后找每个正数和的前两个最大值,然后加在一起返回,最后发现这个做法其实是错误的,仔细想想这个利润没有我们想的这么简单。下面说一下我学习到的一些方法。
- 第一种:这里第一种方法算是一种二分法,就是分两次遍历。第一次遍历是从头至尾遍历,记录每个区间内每一次股票交易获得的最大利润,并且保存到一个新数组内,然后第二次遍历就是从尾向头遍历,选出相应坐标右边区间内一次交易的最大值,左边区间交易的最大值就可以直接从第一次遍历得到的数组获取,两者相加,即可得到两次交易的最大值。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
mini = float('inf')
total_max_profit = 0
first_profit = [0]*len(prices)
for i in range(len(prices)):
mini = min(mini, prices[i])
total_max_profit = max(total_max_profit, prices[i]-mini)
first_profit[i] = total_max_profit
maxi = float('-inf')
max_profit = 0
for i in range(len(prices)-1, 0, -1):
maxi = max(maxi, prices[i])
max_profit = max(max_profit, maxi-prices[i])
total_max_profit = max(total_max_profit, max_profit+first_profit[i-1])
return total_max_profit
- 第二种:这里用到的是动态规划的方法。这个方法其实我也没太弄懂,回头补上。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices:
return 0
n = len(prices)
dp = [[0] * n for _ in range(3)]
for k in range(1, 3):
pre_max = -prices[0]
for i in range(1, n):
pre_max = max(pre_max, dp[k - 1][i - 1] - prices[i])
dp[k][i] = max(dp[k][i - 1], prices[i] + pre_max)
return dp[-1][-1]
- 第三种:我发现还有一种解法特别厉害,这里把问题分成四个状态,分别是第一次买,第一次卖,然后第二次买和第二次卖。然后考虑边界的问题,按照这个思路可以很快能解决问题。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices:
return 0
first_trade_buy = -prices[0]
first_trade_sell = 0
second_trade_buy = -prices[0]
second_trade_sell = 0
for i in range(1, len(prices)):
second_trade_sell = max(second_trade_sell, second_trade_buy + prices[i])
second_trade_buy = max(second_trade_buy, first_trade_sell - prices[i])
first_trade_sell = max(first_trade_sell, first_trade_buy + prices[i])
first_trade_buy = max(first_trade_buy, -prices[i])
return second_trade_sell