持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
动态规划(Dynamic Programming)是一种分阶段求解决策问题的数学思想,它通过把原问题分解为简单的子问题来解决复杂问题。
买卖股票的最佳时机 II
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 返回你能获得的最大 利润
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。 总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。 总利润为 4 。
动态规划
设定dp[i][j] 表示到下标为 i 的这一天,持股状态为 j 时,我们手上拥有的最大现金数。i 表示下标为 i 的那一天,j 表示下标为 i 的那一天是持有股票,还是持有现金。每一天状态可以转移,也可以不动。起始的时候,如果什么都不做,dp[0][0] = 0, 如果持有股票,当前拥有的现金数是当天股价的相反数,即 dp[0][1] = -prices[i]
代码如下:
fun maxProfit(prices: IntArray): Int {
val len = prices.size
if (len < 2) {
return 0
}
val dp = Array(len) { IntArray(2) }
dp[0][0] = 0
dp[0][1] = -prices[0]
for (i in 1 until len) {
dp[i][0] = dp[i - 1][0].coerceAtLeast(dp[i - 1][1] + prices[i])
dp[i][1] = dp[i - 1][1].coerceAtLeast(dp[i - 1][0] - prices[i])
}
return dp[len - 1][0]
}
复杂度分析:
- 时间复杂度:O(N)
- 空间复杂度:O(N)