这三道题都是同一个背景下的变形:给定一个数组,数组里的值表示当日的股票价格,问你如何通过爱情买卖来发家致富?
best time to buy and sell stock i:
最多允许买卖一次
best time to buy and sell stock ii:
不限制买卖次数
best time to buy and sell stock iii:
最多允许买卖两次
对于i:
思路就是在第i个位置抛出时,希望在0~i-1个位置上的最低价买入,才能使得第i个位置的收益最大。然后比较所有可以抛出的位置i,返回最大的收益。
int maxP = 0, minV = prices[0]; for(int i = 1;i<prices.size();i++){ maxP = max(maxP,prices[i]-minV); minV = min(minV,prices[i]); } return maxP;
对于ii:
由于可以无限买,所以思路就是只要赚钱我就卖掉。你可能会问,如果我在i天卖掉,发现i+1天能赚更多,怎么破?血亏!在线等!当然就是在第i天再买入,第i+1天再卖出,虽然规则上不允许同一天有多次买卖,但是这样其实等效于i-1天买入,i天划水,i+1天卖出。
int maxP = 0; for(int i = 1;i<prices.size();i++){ if(prices[i]-prices[i-1] > 0) maxP+=(prices[i] - prices[i-1]); } return maxP;
对于iii:
同样不需要额外的空间,而且只需要O(n)的空间复杂度。思路就是我一开始没有钱,buy1是我第一次买股票之后剩的钱(肯定是负的,我白手起家,借钱买股票啊),sell1是我卖完第一次买的股票之后剩的钱(>=0),buy2是我用上回挣得钱(有可能需要找别人再借一点)买第二次股票,sell2是我卖完第二次股票之后剩下的钱。
int buy1 = INT_MIN, sell1 = 0, buy2 = INT_MIN, sell2 = 0; for(auto p:prices){ buy1 = max(buy1,-p); sell1 = max(sell1,buy1+p); buy2 = max(buy2,sell1-p); sell2 = max(sell2, buy2+p); } return sell2;