数据结构与算法之 leetcode 动态规划股票最佳时机 多次交易

数据结构与算法阿木 发布于 9 天前 3 次阅读


动态规划解决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股票最佳时机问题。我们首先分析了问题,定义了状态和状态转移方程,然后实现了代码,并对代码进行了优化。动态规划是一种强大的算法设计思想,在解决许多实际问题中都有广泛应用。