题目:
My Submissions Question Solution
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
题意:
依旧是买卖股票,最多可以买卖两个交易回合。
思路:
1. 最多两个的意思是可以包括一个。从0到size() - 1这个长度的股市,可以只交易一次,也可以交易两次,如果交易两次的话,两个阶段的买入卖出是分布在两个阶段,我们划分为从0到i以及从i+1到size() - 1这两段。所以我们需要计算出前半段和后半段的收益值。前半段的范围是从[0,1]到[0,size() - 1],后半段是从[size() - 2,size() - 1]到[0,size() -1]。
根据121题求股票一次交易的最大值的方法,我们可以通过从前面往后面扫描以及从后面往前面扫描分别计算出这两段的结果值。然后找出两次交易的profit_front[i] + profit_back[i + 1]最大的收益值。与只交易一次的结果值进行比较。
以上。
代码如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() == 0 || prices.size() == 1)return 0;
int min_price = prices[0];
int max_price = prices[prices.size() - 1];
int * profit_front = new int[prices.size()];
int * profit_back = new int[prices.size()];
profit_front[0] = 0;
profit_back[prices.size() - 1] = 0;
for(int i = 1; i < prices.size(); i++) {
profit_front[i] = max(profit_front[i-1], prices[i] - min_price);
min_price = min(min_price, prices[i]);
}
for(int i = prices.size() - 2; i >= 0; i--) {
profit_back[i] = max(profit_back[i + 1], max_price - prices[i]);
max_price = max(max_price, prices[i]);
}
int result = profit_front[prices.size() - 1];
for(int i = 0; i < prices.size() - 1; i++) {
result = max(result, profit_front[i] + profit_back[i + 1]);
}
return result;
}
};
- 当然还可以使用动态规划的方法来完成这道题目,我们知道最多完成两次交易代表的是买入卖出最多各2次,所以一共有4种状态。假设我们开始手上收益是0元,那么我们遍历 每天的股市的时候,如果手上没有股票,那么可以选择买入这天的股票,买入的话相当于让手上的收益减去股票在这一天的价格,如果我们手上有股票的话可以选择这一天卖出股票,卖出的时候相当于我们手上的收益增加了这只股票的价格。一共有四种状态,
a. 第一种状态手上买入一只股票(第一次买入)
b.第二种状态手上已经有一只股票,那么接下来卖出一只股票(第一次卖出)
c. 第三种状态是手上已经完成了一次买卖,即在状态b的情况下再次入手一只股票。(第二次买入)
d. 第四种状态是手上完成了一次买卖,并且手上还有一只股票,那么可以选择卖出。(第二次卖出)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int size = prices.size();
int profit[2][4] = {INT_MIN, 0, INT_MIN, 0};
int curr = 1, last = 0;
for(int i = 0; i < size; i++) {
profit[curr][0] = max(profit[last][0], -prices[i]);//第一次买入
profit[curr][1] = max(profit[last][1], profit[last][0] + prices[i]);//第一次卖出,建立在手上之前那只股票时的收益状况
profit[curr][2] = max(profit[last][2], profit[last][1] - prices[i]);//第二次买入
profit[curr][3] = max(profit[last][3], profit[last][2] + prices[i]);//第二次卖出
swap(curr, last);
}
return max(profit[last][1], profit[last][3]);
}
};