一句话总结:虽然是困难题,其实都只需要对122 买卖股票的最佳时机II稍作变形即可。
原题链接:123 买卖股票的最佳时机III
相较于买卖股票的最佳时机和股票II来说,本题加了最多操作两次的限制。那么这里实际上就可以直接用滚动数组的思想,用四个变量来表示第一次购买股票后的最大收益firstBuy,第一次卖出股票后的最大收益firstSeal,第二次购买股票后的最大收益secondBuy和第二次卖出股票后的最大收益secondSeal。那么对股票II的题解:
class Solution {
public int maxProfit(int[] prices) {
int buy = -prices[0], seal = 0;
for (int i = 1; i < prices.length; ++i) {
buy = Math.max(buy, seal - prices[i]);
seal = Math.max(seal, buy + prices[i]);
}
return seal;
}
}
稍作变形:
class Solution {
public int maxProfit(int[] prices) {
int firstBuy = -prices[0], firstSeal = 0, secondBuy = -prices[0], secondSeal = 0;
for (int i = 1; i < prices.length; ++i) {
firstBuy = Math.max(firstBuy, -prices[i]);
firstSeal = Math.max(firstSeal, firstBuy + prices[i]);
secondBuy = Math.max(secondBuy, firstSeal - prices[i]);
secondSeal = Math.max(secondSeal, secondBuy + prices[i]);
}
return secondSeal;
}
}
即可解决本题。这里需要思考的仅为每个变量是如何转移而来。
原题链接:188 买卖股票的最佳时机IV
本题为股票III的升级版,其实也就是股票II的pro max版本。因为最多买卖股票k次,所以利用滚动数组思想,设置2 * k个变量,分别为buy[i]和seal[i],以表示第i + 1次买/卖股票后的最大收益。然后一次for循环即可解决问题,转移方程与股票III一致。
class Solution {
public int maxProfit(int k, int[] prices) {
int[] buy = new int[k], seal = new int[k];
for (int i = 0; i < k; ++i) buy[i] = -prices[0];
for (int i = 1; i < prices.length; ++i) {
buy[0] = Math.max(buy[0], -prices[i]);
seal[0] = Math.max(seal[0], buy[0] + prices[i]);
for (int j = 1; j < k; ++j) {
buy[j] = Math.max(buy[j], seal[j - 1] - prices[i]);
seal[j] = Math.max(seal[j], buy[j] + prices[i]);
}
}
return seal[k - 1];
}
}