LeetCode-【陣列】- 買賣股票的最佳時機含手續費
阿新 • • 發佈:2018-12-24
給定一個整數陣列 prices
,其中第 i
個元素代表了第 i
天的股票價格 ;非負整數 fee
代表了交易股票的手續費用。
你可以無限次地完成交易,但是你每次交易都需要付手續費。如果你已經購買了一個股票,在賣出它之前你就不能再繼續購買股票了。
返回獲得利潤的最大值。
示例 1:
輸入: prices = [1, 3, 2, 8, 4, 9], fee = 2 輸出: 8 解釋: 能夠達到的最大利潤: 在此處買入 prices[0] = 1 在此處賣出 prices[3] = 8 在此處買入 prices[4] = 4 在此處賣出 prices[5] = 9 總利潤: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
注意:
0 < prices.length <= 50000
.0 < prices[i] < 50000
.0 <= fee < 50000
.
題解:選擇的關鍵是找到一個最大後是不是能夠賣掉stock,重新開始尋找買入機會。比如序列1 3 2 8,如果發現2小於3就完成交易買1賣3,此時由於fee=2,(3-1-fee)+(8-2-fee)<(8-1-fee),所以說明賣早了,令max是當前最大price,當(max-price[i]>=fee)時可以在max處賣出,且不會存在賣早的情況,再從i開始重新尋找買入機會。
貪心解法:
class Solution { public int maxProfit(int[] prices, int fee) { int n=prices.length; if(n<=1) return 0; int p=0,curP=0; int minP=prices[0],maxP=prices[0]; for(int i=1;i<n;i++){ minP=Math.min(minP,prices[i]); maxP=Math.max(maxP,prices[i]); curP=Math.max(curP,prices[i]-minP-fee); if(maxP-prices[i]>=fee){ p+=curP; curP=0; maxP=prices[i]; minP=prices[i]; } } return p+curP; } }
題解:動態轉移點:手上有沒有股票 進行DP。對於第i天的最大收益,應分成兩種情況,一是該天結束後手裡沒有stock,可能是保持前一天的狀態也可能是今天賣出了,此時令收益為cash;二是該天結束後手中有一個stock,可能是保持前一天的狀態,也可能是今天買入了。由於第i天的情況只和i-1天有關,所以用兩個變數cash和buy就可以,不需要用陣列
動規解法:
class Solution { public int maxProfit(int[] prices, int fee) { int n=prices.length; if(n<=1) return 0; int buy=-prices[0]; int cash=0; for(int i=1;i<n;i++){ cash=Math.max(cash,buy+prices[i]-fee); buy=Math.max(buy,cash-prices[i]); } return cash; } }