动态规划解决LeetCode股票最佳时机问题(多次交易)
在LeetCode等编程竞赛和面试中,股票最佳时机问题是一个经典的问题。该问题要求我们找出在给定价格数组中,通过多次买卖股票所能获得的最大利润。动态规划(Dynamic Programming,DP)是一种解决这类问题的有效方法。本文将围绕动态规划解决股票最佳时机问题,探讨其原理、实现以及优化。
问题分析
假设我们有一个价格数组`prices`,其中`prices[i]`表示第`i`天的股票价格。我们需要通过多次买卖股票来获得最大利润。每次买卖股票都需要支付一定的交易费用`fee`。
动态规划状态定义
为了使用动态规划解决此问题,我们需要定义一个状态数组`dp`,其中`dp[i][j]`表示在第`i`天,持有`j`股股票时的最大利润。
- `dp[i][0]`:在第`i`天不持有股票时的最大利润。
- `dp[i][1]`:在第`i`天持有股票时的最大利润。
状态转移方程
根据状态定义,我们可以得到以下状态转移方程:
- `dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee)`:在第`i`天不持有股票,可以选择继续不持有或者卖出股票。
- `dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])`:在第`i`天持有股票,可以选择继续持有或者买入股票。
初始状态
- `dp[0][0] = 0`:第一天不持有股票,利润为0。
- `dp[0][1] = -prices[0] - fee`:第一天买入股票,利润为负。
代码实现
下面是使用动态规划解决股票最佳时机问题的Python代码实现:
python
def maxProfit(prices, fee):
n = len(prices)
if n < 2:
return 0
初始化状态数组
dp = [[0] 2 for _ in range(n)]
dp[0][0] = 0
dp[0][1] = -prices[0] - fee
遍历状态转移方程
for i in range(1, n):
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee)
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
返回最终结果
return dp[-1][0]
示例
prices = [1, 3, 2, 8, 4, 9]
fee = 2
print(maxProfit(prices, fee)) 输出: 8
优化
上述代码的时间复杂度为O(n),空间复杂度也为O(n)。我们可以通过一维数组来优化空间复杂度。
python
def maxProfitOptimized(prices, fee):
n = len(prices)
if n < 2:
return 0
初始化状态数组
dp = [0, -prices[0] - fee]
遍历状态转移方程
for i in range(1, n):
dp[0] = max(dp[0], dp[1] + prices[i] - fee)
dp[1] = max(dp[1], dp[0] - prices[i])
返回最终结果
return dp[0]
示例
prices = [1, 3, 2, 8, 4, 9]
fee = 2
print(maxProfitOptimized(prices, fee)) 输出: 8
总结
本文通过动态规划的方法解决了LeetCode股票最佳时机问题。我们首先分析了问题,定义了状态和状态转移方程,然后实现了代码,并对代码进行了优化。动态规划是一种强大的算法设计思想,在解决许多实际问题中都有广泛应用。
Comments NOTHING