假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可获得的最大利润是多少?
例如,一只股票在某些时间节点的价格为{9,11,8,5,7,12,16,14}。如果我们能在价格为5的时候买入并在价格为16时卖出,则能获得最大的利润为11.
剑指Offer(第2版):P304
LeetCode-121:Best Time to Buy and Sell Stock (一次股票交易最大利润)
class Solution {
public:
int maxProfit(vector<int> prices) {
int length = prices.size();
if (length < 2)
return 0;
int minPrice = prices[0];
int maxDiff = prices[1] - minPrice;
for (int i = 2; i < length; ++i) {
if (prices[i - 1] < minPrice)
minPrice = prices[i - 1];
int currentDiff = prices[i] - minPrice;
if (currentDiff > maxDiff)
maxDiff = currentDiff;
}
return maxDiff;
}
};
与题目一不同的是,这里可以多次卖出。
LeetCode-122:Best Time to Buy and Sell Stock II (多次股票交易最大利润)
class Solution {
public:
int maxProfit(vector<int> prices) {
int length = prices.size();
if (length < 2)
return 0;
int maxProfit = 0;
for (int i = 0; i < length - 1; i++) {
int profit = prices[i + 1] - prices[i];
if (profit > 0)
maxProfit += profit;
}
return maxProfit;
}
};
与题目一不同的是,这里做出了限制,最多实现两次交易。
LeetCode-123:Best Time to Buy and Sell Stock III
class Solution {
public:
/** * 计算最大收益 * @param prices : 每日价格 * @return : 最大收益 * @note : 至多进行两次买卖 */
int maxProfit(vector<int>& prices) {
int pricesSize = prices.size();
/* 如果价格数据为空或只有一个数据,返回0 */
if (pricesSize <= 1) return 0;
vector<int> maxProfitDuringFormmerDays(pricesSize),
maxProfitDuringLatterDays(pricesSize);
int day, diff, minPrice, maxPrice, maxProfit;
/* 计算某一天极其之前所有时间内的最大利益 */
minPrice = prices[0];
maxProfit = 0;
maxProfitDuringFormmerDays[0] = 0;
for (day = 1; day < pricesSize; ++day) {
diff = prices[day] - minPrice;
if (diff < 0) minPrice = prices[day];
else if (diff > maxProfit) maxProfit = diff;
maxProfitDuringFormmerDays[day] = maxProfit;
}
/* 计算某一天极其之后所有时间内价格的最利益 */
maxPrice = prices[pricesSize - 1];
maxProfit = 0;
maxProfitDuringLatterDays[pricesSize - 1] = 0;
for (day = pricesSize - 2; day > -1; --day) {
diff = maxPrice - prices[day];
if (diff < 0) maxPrice = prices[day];
else if (diff > maxProfit) maxProfit = diff;
maxProfitDuringLatterDays[day] = maxProfit;
}
/* 计算最大收益 */
int sum;
maxProfit = 0;
for (day = 0; day < pricesSize; ++day) {
sum = maxProfitDuringFormmerDays[day] + maxProfitDuringLatterDays[day];
if (sum > maxProfit) maxProfit = sum;
}
return maxProfit;
}
};
Buy1[i]表示前i天做第一笔交易买入股票后剩下的最多的钱;
Sell1[i]表示前i天做第一笔交易卖出股票后剩下的最多的钱;
Buy2[i]表示前i天做第二笔交易买入股票后剩下的最多的钱;
Sell2[i]表示前i天做第二笔交易卖出股票后剩下的最多的钱;
那么:
可以发现上面四个状态都是只与前一个状态有关,所以可以不使用数组而是使用变量来存储即可。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int buy1=numeric_limits<int>::min();
int buy2=numeric_limits<int>::min();
int sell1=0;
int sell2=0;
for(int i=0;i<prices.size();i++)
{
sell2=max(sell2,buy2+prices[i]);
buy2=max(buy2,sell1-prices[i]);
sell1=max(sell1,buy1+prices[i]);
buy1=max(buy1,-prices[i]);
}
return sell2;
}
};