题目1:121. 买卖股票的最佳时机
动规方程的定义 并不算好想。
思路: 既然是状态推导, 那么就应该记录不同的状态。
此题即持有 与不持有两种状态的记录。
// @lc code=start
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
if prices.count == 1 { return 0 }
// 分析状态: 当天是否持有。
// 所以每天用一个元祖记录(a, b)
// 其中:a代表持有股票所得最多现金, b代表不持有股票可获得的最多现金
var dp = Array(repeating: (0, 0), count: prices.count)
dp[0] = (-prices[0], 0)
for i in 1..<prices.count {
// 持有: 上一天就持有 || 今天买入
// 只可以买卖一次,所以买入前的现金即为0
dp[i].0 = max(dp[i - 1].0, -prices[i])
// 未持有: 上一天就未持有 || 今天卖出
dp[i].1 = max(dp[i - 1].1, dp[i - 1].0 + prices[i])
}
// 必然是最后一天不持有结果更大
return dp[prices.count - 1].1
}
}
// @lc code=end
题目2:122.买卖股票的最佳时机II
与买卖股票1的区别 就在于可以买卖多次。
所以dp[i].0 的取值 如果计算上一天不持有,今天买入的话。 就应该使用dp[i - 1].1,而不是现金总数为0
// @lc code=start
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
if prices.count == 1 { return 0 }
// dp[i].0 第i天持有 , dp[i].1 第i天不持有
var dp = Array(repeating: (0, 0), count: prices.count)
dp[0] = (-prices[0], 0)
for i in 1..<prices.count {
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])
}
return dp[prices.count - 1].1
}
}
// @lc code=end
题目3:123.买卖股票的最佳时机III
延续买卖股票1的思路, 需要记录所有状态进行递推。
第二次操作 基于第一次操作进行。
dp[i].3 = max(dp[i - 1].3, dp[i - 1].2 - prices[i])
// 动规递推
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
if prices.count == 1 { return 0 }
// 不操作、第一次买入、第一次卖出、第二次买入、第二次卖出
var dp = Array(repeating: (0, 0, 0, 0, 0), count: prices.count)
dp[0] = (0, -prices[0], 0, -prices[0], 0)
for i in 1..<prices.count {
dp[i].0 = dp[i - 1].0
dp[i].1 = max(dp[i - 1].1, dp[i - 1].0 - prices[i])
dp[i].2 = max(dp[i - 1].2, dp[i - 1].1 + prices[i])
dp[i].3 = max(dp[i - 1].3, dp[i - 1].2 - prices[i])
dp[i].4 = max(dp[i - 1].4, dp[i - 1].3 + prices[i])
}
return dp[prices.count - 1].4
}
}
// 优化滚动数组节省空间
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
if prices.count == 1 { return 0 }
// 使用滚动数组。
// 不操作、第一次买入、第一次卖出、第二次买入、第二次卖出
var status = (0, -prices[0], 0, -prices[0], 0)
for i in 1..<prices.count {
status.4 = max(status.4, status.3 + prices[i])
status.3 = max(status.3, status.2 - prices[i])
status.2 = max(status.2, status.1 + prices[i])
status.1 = max(status.1, status.0 - prices[i])
}
return status.4
}
}