/* 找一次操作能获取最大利润的一次交易(即题目121)的idxBuy和idxSell,这次交易称为首次交易 然后分5中情况: 情况1:最优解就只有“首次交易” 情况2:“首次交易”加上左边的交易得到最优解 情况3:“首次交易”加上右边的交易得到最优解 情况4:“首次交易”不做,两边的交易得到最优解 情况5:“首次交易”不做,idxBuy和idxSell中间找亏损最大的交易idxBuy2,idxSell2,然后idxBuy买,idxBuy2卖,idxSell2买,idxSell卖就是最优解 */ class Solution { public: #define MAX(a,b) ((a)>(b)?(a):(b)) int maxProfit(vector<int>& prices) { if(prices.size() < 2)return 0; //处理首次交易 int idxBuy = 0 ,idxSell = 0; int profitOrigin = this->maxProfitOfOne(prices, 0, prices.size()-1,&idxBuy,&idxSell); int maxProfit = profitOrigin;//默认 //算出左侧交易利润 int profitLeft = this->maxProfitOfOne(prices, 0, idxBuy-1); //算出右侧交易利润 int profitRight = this->maxProfitOfOne(prices, idxSell+1, prices.size()-1); //算出情况1,2,3,4的最大利润 maxProfit = MAX(profitLeft + profitOrigin, profitRight + profitOrigin); maxProfit = MAX(maxProfit,profitLeft + profitRight); //算出idxBuy,idxSell之间的最大亏损,反过来操作就是更大的盈利 vector<int> pricesRe = prices; reverse(pricesRe.begin(),pricesRe.end()); int maxProfitEx = this->maxProfitOfOne(pricesRe, pricesRe.size() -1- idxSell, pricesRe.size() -1- idxBuy); return MAX(maxProfitEx+profitOrigin,maxProfit); } int maxProfitOfOne(vector<int>& prices, int left, int right,int *pMin=NULL,int *pMax=NULL) { if (left >= right) return 0; int minLop = left, maxLop = left; int maxProfit = 0; int idx = minLop + 1; while (idx < right + 1) { if (prices[idx] > prices[maxLop]) {//find larger maxLop = idx; int profit = prices[maxLop] - prices[minLop]; if (profit > maxProfit) { maxProfit = profit; if(pMin)*pMin = minLop; if(pMax)*pMax = maxLop; } } else if (prices[idx] < prices[minLop]) {//find smaller minLop = idx; maxLop = idx; } idx++; } return maxProfit; } };