188. 買賣股票的最佳時機 IV
做完上一道題後再看就簡單許多了。股票問題的重點就在於兩點:
- 找到所有的狀態
- 狀態如何轉移
對於本題,一共包含2*k
種狀態(第1,2...k次持有,第1,2...k次賣出)。狀態間如何轉移呢?見下圖
class Solution {
public int maxProfit(int k, int[] prices) {
int[] states = new int[2*k];
Arrays.fill(states, Integer.MIN_VALUE);
for(int i = 0; i < prices.length; i++){
for(int j = 0; j < k; j++){
states[2*j] = Math.max(states[2*j],
2*j == 0 ? -prices[i] : states[2*j-1] - prices[i]);
states[2*j+1] = Math.max(states[2*j+1],
states[2*j] + prices[i]);
}
}
return states[2*k-1];
}
}
309. 買賣股票的最佳時機含冷凍期
難度還是挺大,儘管最後寫出來了,但感覺寫完自己也不是很確定。也是兩部,確定所有的狀態,再確定狀態如何轉移。
- 包含三種狀態,分別為 非冷凍(未持有) 冷凍(未持有) 持有
- 狀態轉移圖
- 確定好這兩點再去實現程式碼就不會亂套了
class Solution {
public int maxProfit(int[] prices) {
int[] stat = new int[3];
// 三種狀態
//分別為 非冷凍(未持有) 冷凍(未持有) 持有
stat[0] = 0; stat[1] = 0; stat[2] = -1 * prices[0];
for(int i = 1; i < prices.length; i++){
stat[0] = Math.max(stat[0], stat[1]); //當天非冷凍 前一天非冷凍|前一天冷凍
stat[1] = stat[2] + prices[i-1]; //當天冷凍 一定是前一天持有
stat[2] = Math.max(stat[2], stat[0]-prices[i]); //當天持有 前一天持有|今天非冷凍
}
return Math.max(Math.max(stat[0], stat[1]), stat[2] + prices[prices.length-1]);
//最後一天三種狀態,非持有兩種, 持有需要賣出再比較
}
}
714. 買賣股票的最佳時機含手續費
class Solution {
public int maxProfit(int[] prices, int fee) {
int stat1 = -1 * prices[0] - fee;
int stat2 = 0;
for(int i = 1; i < prices.length; i++){
stat1 = Math.max(stat1, stat2 - fee - prices[i]);
stat2 = Math.max(stat2, stat1 + prices[i]);
}
return stat2;
}
}