121. Best Time to Buy and Sell Stock
題意爲只可買入一次,並賣出一次,要求獲取的利潤最高。最簡單的思路就是兩層循環,比較每一個數與後面的數的差值,以求出當前能獲取的最大差值,即爲最大利潤,算法的時間複雜度即O(n²)。我們可以考慮優化算法,我們每獲取一個數時,我們其實只需要跟這個數之前最小的那個數做比較
,就可以知道這個爲出口時,能獲取的最大利潤值,再通過比較所有出口的最大利潤值,來獲取一個全局最優解。
public int maxProfit(int[] prices) {
if (prices == null || prices.length <= 1) {
return 0;
}
int minValue = Integer.MAX_VALUE;
int maxProfit = 0;
for (int price : prices) {
if (price < minValue) {
// 更新當前的遍歷過得數組的最小值
minValue = price;
} else if (price - minValue > maxProfit) {
// 計算當前位置爲出口時的最大利潤
// 如超過全局最優,則覆蓋全局最優
maxProfit = price - minValue;
}
}
return maxProfit;
}
122. Best Time to Buy and Sell Stock II
第二題與第一題的區別在於,現在不需要考慮買賣的次數,可以無數次進行買入賣出。那解題思路變的很容易,我們只需要不斷加上數組連續數之間的差值,即能得到一個總的利潤(貪心的思想)。代碼如下:
public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int maxProfit = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] - prices[i - 1] > 0) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
123. Best Time to Buy and Sell Stock III
對於第三題,其約束了買入賣出的次數,至多兩次。我們可以考慮,將買入賣出2次,看成了四次行爲,即買1
、賣1
、買2
、賣2
,因爲只有手頭上的錢纔是錢,即購買股票可視爲支出(或虧損),即購買 price 時,當日的收益爲 buy = -price,而賣出視爲收入,收益需要考慮支出,即賣出價位爲 price 時,總收益爲 buy + price。而,我們第二次的購買,會受到第一次買入結果的影響,因此,第二次購入時,其收益爲 sell1 - price。代碼如下:
public int maxProfit(int[] prices) {
int b1 = Integer.MIN_VALUE, s1 = 0;
int b2 = Integer.MIN_VALUE, s2 = 0;
for (int price : prices) {
// 第一次買入,支出 price
b1 = Math.max(b1, -price);
// 第一次賣出,盈利 price + b1
s1 = Math.max(s1, price + b1);
// 第二次買入,受第一次買賣的影響,因此有 s1 的本金,支出 price
b2 = Math.max(b2, s1 - price);
// 第二次買入,盈利 price + b2
s2 = Math.max(s2, price + b2);
}
return s2;
}