更多算法题的题解见:算法刷题题解汇总(持续更新中)
题目:力扣309—买卖股票的最佳时机含冷冻期 | 掘金—股票市场交易策略优化
问题描述
给定一个数组,数组中的第 i
个元素代表第 i
天的股票价格。小R需要设计一个算法来实现最大利润。
股票交易规则如下:
- 小R可以多次买卖股票,但在买入新的股票前必须卖出之前的股票。
- 每次卖出股票后存在一天的冷冻期,在冷冻期内小R不能购买股票。
你的任务是帮助小R计算出在遵守交易规则的情况下能够获得的最大利润。
stocks
: 一个整数列表,表示连续几天内的股票价格。
ps: 以上为掘金对应题目题解,力扣309内容与其一样
方法:动态规划
这是一个动态规划问题,首先,我们定义两个变量 f0
和 f1
,它们分别代表两种状态:
f0
:表示在第i
天结束时,小R不持有股票的最大利润。f1
:表示在第i
天结束时,小R持有股票的最大利润。
此外,我们还定义了一个变量 pre
,它用来存储前一天不持有股票时的最大利润,这是因为在卖出股票后会有一个冷冻期,所以我们需要这个值来计算冷冻期后的状态。
接下来,我们遍历股票价格数组 stocks
,对于每一天的价格 price
,我们做以下两步操作:
- 计算新的
f0
(即newF
),它表示第i+1
天结束时,小R不持有股票的最大利润。这个值可以是前一天不持有股票的最大利润f0
,或者是前一天持有股票并在今天卖出后的利润f1 + price
。 - 更新
f1
,它表示第i+1
天结束时,小R持有股票的最大利润。这个值可以是前一天持有股票的最大利润f1
,或者是前一天不持有股票并在今天买入后的利润pre - price
。
在每一步计算之后,我们需要更新 pre
为前一天不持有股票的最大利润,即 pre = f0
,然后将 newF
赋值给 f0
,以便在下一次循环中使用。
最后,返回 f0
,它将包含在整个交易周期结束时,小R能够获得的最大利润。以下是代码的solution函数代码:
public static int solution(int[] stocks) {
int pre = 0;
int f0 = 0;
int f1 = Integer.MIN_VALUE;
for (int price : stocks) {
int newF = Math.max(f0, f1 + price);
f1 = Math.max(f1, pre - price);
pre = f0;
f0 = newF;
}
return f0;
}
复杂度分析
1.时间复杂度:
- 循环遍历了股票价格数组
stocks
一次,所以时间复杂度是O(n)
,其中 n 是股票价格数组的长度。
2.空间复杂度:
- 代码中使用了固定数量的变量
pre
,f0
,f1
,并没有使用额外的数据结构来存储中间结果,因此空间复杂度是O(1)
。