点评:整个思考化简过程还是没有跳出整个框架。k=1的时候通过写上发现k这个状态可以去掉,初始化正好也有机的结合到了转移方程中,最后例行优化空间。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
#状态,选择。有三种状态,第几天,第几次交易。三种状态转换,buy、sell、rest,使得在0-1间转换。
#dp[i][k][0]和dp[i][k][1]分别代表第i天,第k次交易的最大利润。
#转移方程(根据状态自动机可以写出):dp[i][k][0]= max(dp[i-1][k][0], dp[i-1][k][1]+price) dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0]-price)
#初始化 判断i-1=-1的时,dp[i][k][0] = 0,dp[i][k][1] = -price
#3
#2
#1
#GO!
N = len(prices)
dp = [[0 for i in range(2)] for j in range(N)]
dp_i_0, dp_i_1 = 0, float('-inf')
for i in range(N):
dp_i_0 = max(dp_i_0, dp_i_1+prices[i])
dp_i_1 = max(dp_i_1, -prices[i])
return dp_i_0
122. 买卖股票的最佳时机 II
点评:k等于无限,也不需要记录k状态。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
#有了第一题的基础,直接开干!!!
N = len(prices)
dp_i_0, dp_i_1 = 0, float('-inf')
for i in range(N):
if i - 1 == -1:
dp_i_0 = 0
dp_i_1 = -prices[i]
continue
dp_i_0 = max(dp_i_0, dp_i_1 + prices[i])
dp_i_1 = max(dp_i_1, dp_i_0- prices[i])
return dp_i_0
123. 买卖股票的最佳时机 III
点评:k=2,需要考虑k,并且是从后往前考虑,因为k的时候需要k-1时候的状态。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
N = len(prices)
if N == 0:return 0
dp = [[[0 for j in range(2)] for k in range(2+1)] for i in range(N)]
for i in range(N):
for k in range(2, 0, -1):
if i-1==-1:
dp[i][1][0], dp[i][0][1] = 0, float('-inf')
dp[i][1][0], dp[i][1][1] = 0, -prices[i]
dp[i][2][0], dp[i][2][1] = 0, -prices[i]
continue
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1]+prices[i])
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0]-prices[i])
return dp[-1][-1][0]
188. 买卖股票的最佳时机 IV
点评:k无限的时候,这里需要考虑一个用例。即k大于n/2的,因为至少没两次交易才能完整表示输入输出,所以大于n/2的视为无限,而无限可以减少空间和k状态这一维度的时间复杂度。
class Solution:
def maxProfit(self, k: int, prices: List[int]) -> int:
N = len(prices)
if N == 0:return 0
def maxProfit_k_inf(prices):
dp_i_0, dp_i_1 = 0, -float('inf')
for price in prices:
t = dp_i_0
dp_i_0 = max(dp_i_0, dp_i_1+price)
dp_i_1 = max(dp_i_1, dp_i_0-price)
return dp_i_0
if k > N // 2:
return maxProfit_k_inf(prices)
dp = [[[0 for j in range(2)] for kk in range(k+1)]for i in range(N)]
for i in range(N):
if i - 1 == -1:
dp[i][0][0], dp[i][0][1] = 0, float('-inf')
for j in range(1, k+1):
dp[i][j][0], dp[i][j][1] = 0, -prices[i]
continue
for kk in range(k, 0, -1):
dp[i][kk][0] = max(dp[i-1][kk][0], dp[i-1][kk][1]+prices[i])
dp[i][kk][1] = max(dp[i-1][kk][1], dp[i-1][kk-1][0]-prices[i])
return dp[-1][-1][0]
309.最佳买卖股票时机含冷冻期
点评:状态转移方程改一下。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
N = len(prices)
if N == 0:return 0
dp = [[0 for j in range(2)] for i in range(N)]
for i in range(N):
if i - 1 == -1:
dp[i][0], dp[i][1] = 0, -prices[i]
continue
dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-2][0]-prices[i])
return dp[-1][0]
714.买卖股票的最佳时机含手续费
点评:每次买入或卖出的时候减一个手续费。
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
N = len(prices)
if N == 0:return 0
dp = [[0 for j in range(2)] for i in range(N)]
for i in range(N):
if i - 1 == -1:
dp[i][0], dp[i][1] = 0, -prices[i]-fee
continue
dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]-fee)
return dp[-1][0]