LeetCode 309. 最佳买卖股票时机含冷冻期
题目链接:309. 最佳买卖股票时机含冷冻期
思路:使用动规五部曲分析:
-
确定dp数组及其下标的含义
我们在第 i 天会遇到以下4种情况:- 买入股票或之前买入股票并维持现状
- 卖出股票且已经过了冷冻期
- 卖出股票且没过冷冻期(即今天刚卖出股票)
- 今天为冷冻期
所以我们的dp状态可以由一个长度为4的列表来保存。
-
确定递推公式
在第 i 天遇到这支股票后,我们共有两种状态(持有股票或未持有股票),且有两种选择(买或者不买),而上述的4种dp数组的状态的递推公式为:
d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , m a x ( d p [ i − 1 ] [ 1 ] − p r i c e s [ i ] , d p [ i − 1 ] [ 3 ] − p r i c e s [ i ] ) ) dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1] - prices[i], dp[i - 1][3] - prices[i])) dp[i][0]=max(dp[i−1][0],max(dp[i−1][1]−prices[i],dp[i−1][3]−prices[i]))
d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 3 ] ) dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]) dp[i][1]=max(dp[i−1][1],dp[i−1][3])
d p [ i ] [ 2 ] = d p [ i − 1 ] [ 0 ] + p r i c e s [ i ] dp[i][2] = dp[i - 1][0] + prices[i] dp[i][2]=dp[i−1][0]+prices[i]
d p [ i ] [ 3 ] = d p [ i − 1 ] [ 2 ] dp[i][3] = dp[i - 1][2] dp[i][3]=dp[i−1][2] -
dp数组初始化
如果在第一天买入股票,那一定就花费了第一支股票的价钱,为-prices[0],所以将dp[i][0]初始化为-prices[0],其余状态初始化为0。 -
确定遍历顺序
从前向后遍历。 -
打印状态一、二、三中的较大者即可。
go版本:
func maxProfit(prices []int) int {
n := len(prices)
if n < 2 {
return 0
}
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, 4)
}
dp[0][0] = -prices[0]
for i := 1; i < n; i++ {
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1] - prices[i], dp[i - 1][3] - prices[i]))
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3])
dp[i][2] = dp[i - 1][0] + prices[i]
dp[i][3] = dp[i - 1][2]
}
return max(dp[n - 1][1], max(dp[n - 1][2], dp[n - 1][3]))
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( n ) O(n) O(n)
LeetCode 714. 买卖股票的最佳时机含手续费
题目链接:714. 买卖股票的最佳时机含手续费
思路:与122.买卖股票的最佳时机II这篇博客的思路一致,就在完成一次买卖股票的时候扣除一次手续费即可。
go版本:
func maxProfit(prices []int, fee int) int {
n := len(prices)
dp := make([][]int, n)
for i:=0; i<n; i++ {
dp[i] = make([]int, 2)
}
dp[0][0] -= prices[0]
dp[0][1] = 0
for i := 1; i < n; i++ {
dp[i][0] = max(dp[i - 1][0], dp[i-1][1]-prices[i])
dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]-fee)
}
return dp[n-1][1]
}
func max(i, j int) int {
if i > j {
return i
} else {
return j
}
}
时间复杂度: O ( n ) O(n) O(n),空间复杂度: O ( n ) O(n) O(n)