買(mǎi)賣(mài)股票系列
【leetcode】40-best-time-to-buy-and-sell-stock 力扣 121. 買(mǎi)賣(mài)股票的最佳時(shí)機(jī)
【leetcode】41-best-time-to-buy-and-sell-stock-ii 力扣 122. 買(mǎi)賣(mài)股票的最佳時(shí)機(jī) II
【leetcode】42-best-time-to-buy-and-sell-stock-iii 力扣 123. 買(mǎi)賣(mài)股票的最佳時(shí)機(jī) III
【leetcode】43-best-time-to-buy-and-sell-stock-iv 力扣 188. 買(mǎi)賣(mài)股票的最佳時(shí)機(jī) IV
【leetcode】44-best-time-to-buy-and-sell-stock-with-cooldown 力扣 309. 買(mǎi)賣(mài)股票的最佳時(shí)機(jī)包含冷凍期
開(kāi)源地址
為了便于大家學(xué)習(xí)爪幻,所有實(shí)現(xiàn)均已開(kāi)源须误。歡迎 fork + star~
題目
給定一個(gè)整數(shù)數(shù)組prices京痢,其中第 prices[i] 表示第 i 天的股票價(jià)格 。
設(shè)計(jì)一個(gè)算法計(jì)算出最大利潤(rùn)祭椰。在滿足以下約束條件下,你可以盡可能地完成更多的交易(多次買(mǎi)賣(mài)一支股票):
賣(mài)出股票后钉赁,你無(wú)法在第二天買(mǎi)入股票 (即冷凍期為 1 天)你踩。
注意:你不能同時(shí)參與多筆交易(你必須在再次購(gòu)買(mǎi)前出售掉之前的股票)。
示例 1:
輸入: prices = [1,2,3,0,2]
輸出: 3
解釋: 對(duì)應(yīng)的交易狀態(tài)為: [買(mǎi)入, 賣(mài)出, 冷凍期, 買(mǎi)入, 賣(mài)出]
示例 2:
輸入: prices = [1]
輸出: 0
提示:
1 <= prices.length <= 5000
0 <= prices[i] <= 1000
v1-DP
整體思路
我們考慮 3 個(gè)場(chǎng)景:
// a1: 手上持有股票的最大收益
// a2: 手上不持有股票吩谦,并且處于冷凍期中的累計(jì)最大收益
// a3: 手上不持有股票膝藕,并且不在冷凍期中的累計(jì)最大收益
要想計(jì)算最大的利潤(rùn)束莫,只需要考慮不持有股票的對(duì)比就可。
至于 a1策严,是為了中轉(zhuǎn)計(jì)算。
初始化
a1[0] = -prices[0];
遞推公式
a1
a1 什么時(shí)候手上會(huì)有股票? 必須是買(mǎi)入的時(shí)候妻导。
一種是上次就持有倔韭;還有一種處于 a3 狀態(tài)瓢对,然后買(mǎi)入硕蛹。
a1[i] = max(a1[i-1], a3[i-1] - prices[i]);
a2
a2: 手上不持有股票,并且處于冷凍期中的累計(jì)最大收益
什么場(chǎng)景會(huì)不持有法焰,則處于冷凍期埃仪?
就是持有股票,然后直接賣(mài)出了颁股?
a2[i] = a1[i-1] + prices[i];
a3
a3: 手上不持有股票,并且不在冷凍期中的累計(jì)最大收益
什么場(chǎng)景不持有股票豌蟋,且不處于冷凍期桑滩。
1)此時(shí)不能直接賣(mài)出允睹,因?yàn)闀?huì)被冷凍缭受;所以
2)昨天分為兩個(gè)場(chǎng)景:a2 狀態(tài)该互;或者 a3 狀態(tài)
a3[i] = max(a3[i-1], a2[i-1])
完整的偽代碼
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
// a1: 手上持有股票的最大收益 主要是為了計(jì)算存儲(chǔ)宇智,結(jié)果不考慮此場(chǎng)景。
// a2: 手上不持有股票喂分,并且處于冷凍期中的累計(jì)最大收益
// a3: 手上不持有股票机蔗,并且不在冷凍期中的累計(jì)最大收益
int a1[] = new int[n];
int a2[] = new int[n];
int a3[] = new int[n];
// 初始化
a1[0] = -prices[0];
for (int i = 1; i < n; ++i) {
// 持有股票:昨天持有 OR 買(mǎi)入
a1[i] = Math.max(a1[i-1], a3[i-1] - prices[i]);
// 手上不持有股票萝嘁,并且處于冷凍期中的累計(jì)最大收益: 必定是賣(mài)出
a2[i] = a1[i-1] + prices[i];
// 手上不持有股票牙言,并且不在冷凍期中的累計(jì)最大收益: 昨天可能是 a3; a2
a3[i] = Math.max(a2[i-1], a3[i-1]);
}
// 手里沒(méi)有股票對(duì)比即可
return Math.max(a2[n-1], a3[n-1]);
}
}
評(píng)價(jià)
這一道題嚴(yán)格點(diǎn)說(shuō)還是比較難的,就是我們必須通過(guò) 3 個(gè)狀態(tài)數(shù)組來(lái)處理咱枉。
所以需要前面題目的鋪墊。